Существует ли команда Unix для добавления некоторых строковых данных в текстовый файл?
Что-то вроде:
prepend "to be prepended" text.txt
Существует ли команда Unix для добавления некоторых строковых данных в текстовый файл?
Что-то вроде:
prepend "to be prepended" text.txt
sed -i.old '1s;^;to be prepended;' inFile
-i
записывает изменение на место и создает резервную копию, если указано какое-либо расширение. (В данном случае .old
)1s;^;to be prepended;
заменяет начало первой строки заданной строкой замены, используя ;
в качестве разделителя команд.printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt
Я удивлен, что никто не упомянул об этом.
cat <(echo "before") text.txt > newfile.txt
что, возможно, более естественно, чем принятый ответ (распечатка чего-либо и передача его в команду подстановки лексикографически нелогична).
... и угоня сказанное Райаном выше, с sponge
вам не нужен временный файл:
sudo apt-get install moreutils
<<(echo "to be prepended") < text.txt | sponge text.txt
ОБНОВЛЕНИЕ: похоже, это не работает в Bourne Shell /bin/sh
Используя здесь-строку - <<<
, вы можете сделать:
<<< "to be prepended" < text.txt | sponge text.txt
Это одна из возможностей:
(echo "to be prepended"; cat text.txt) > newfile.txt
вам, вероятно, нелегко обойти промежуточный файл.
Альтернативы (может быть громоздким при экранировании оболочки):
sed -i '0,/^/s//to be prepended/' text.txt
Это будет работать для формирования результата. - означает стандартный вход, который через трубку подается из эха.
echo -e "to be prepended \n another line" | cat - text.txt
Чтобы переписать файл, требуется временный файл, так как он не может вернуться обратно во входной файл.
echo "to be prepended" | cat - text.txt > text.txt.tmp
mv text.txt.tmp text.txt
Предпочитаю Адаму ответить
Мы можем упростить использование губки. Теперь нам не нужно создавать временный файл и переименовывать его с помощью
echo -e "to be prepended \n another line" | cat - text.txt | sponge text.txt
Наверное, ничего встроенного, но вы могли бы написать свой собственный довольно легко, например:
#!/bin/bash
echo -n "$1" > /tmp/tmpfile.$$
cat "$2" >> /tmp/tmpfile.$$
mv /tmp/tmpfile.$$ "$2"
Что-то вроде этого хотя бы...
Если допустимо заменить входной файл:
Примечание. Для этого могут иметь неожиданные побочные эффекты, особенно , заменяя символическую ссылку на обычный файл, возможно, заканчивая разными правами на файл и изменяя создание файла (рождение) дата.
sed -i
, как в ответе Prince John Wesley, пытается как минимум восстановить исходные разрешения, но другие ограничения применяются.
{ printf 'line 1\nline 2\n'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt
Примечание. Использование групповой команды { ...; ... }
более эффективно, чем использование подоболочки ((...; ...)
).
Если входной файл должен быть отредактирован на месте (сохраняя свой индексный дескриптор со всеми его атрибутами):
Использование почтенного ed
Утилита POSIX:
Примечание: ed
всегда считывает входной файл в целом в память.
ed -s text.txt <<'EOF'
1i
line 1
line 2
.
w
EOF
-s
подавлено сообщения о статусе ed
.ed
как многострочный здесь-документ (<<'EOF' ... EOF
), то есть через STDIN.1i
делает 1
(1-я строка) текущей строкой и запускает режим вставки (i
)..
в своей строке.w
записывает результат обратно во входной файл (для тестирования замените w
на ,p
только для печати результата без изменения входного файла).В некоторых случаях предварительный текст может быть доступен только из stdin. Тогда эта комбинация будет работать.
echo "to be prepended" | cat - text.txt | tee text.txt
Если вы хотите опустить вывод tee
, добавьте > /dev/null
.
Решение:
printf '%s\n%s' 'text to prepend' "$(cat file.txt)" > file.txt
Обратите внимание, что это безопасно для всех типов входов, потому что нет расширений. Например, если вы хотите добавить [email protected]#$%^&*()ugly text\n\t\n
, он будет работать:
printf '%s\n%s' '[email protected]#$%^&*()ugly text\n\t\n' "$(cat file.txt)" > file.txt
Последняя часть, оставленная для рассмотрения, - удаление пробелов в конце файла во время подстановки команды "$(cat file.txt)"
. Все обходные пути для этого относительно сложны. Если вы хотите сохранить новые строки в конце файла file.txt, см. Это: fooobar.com/questions/26162/...
Другой способ: sed
:
sed -i.old '1 {i to be prepended
}' inFile
Если строка, которая должна быть добавлена, является многострочной:
sed -i.old '1 {i\
to be prepended\
multiline
}' inFile
Как проверено в Bash (в Ubuntu), если начать с тестового файла через;
echo "Original Line" > test_file.txt
вы можете выполнить;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
или, если версия bash слишком старая для $(), вы можете использовать обратные метки;
echo "'echo "New Line"; cat test_file.txt'" > test_file.txt
и получите следующее содержимое "test_file.txt";
New Line
Original Line
Нет промежуточного файла, просто bash/echo.
Еще одно довольно прямое решение:
$ echo -e "string\n" $(cat file)
Если вам нравится vi/vim, это может быть больше вашего стиля.
printf '0i\n%s\n.\nwq\n' prepend-text | ed file
# create a file with content..
echo foo > /tmp/foo
# prepend a line containing "jim" to the file
sed -i "1s/^/jim\n/" /tmp/foo
# verify the content of the file has the new line prepened to it
cat /tmp/foo
Я бы порекомендовал определить функцию, а затем импортировать и использовать ее там, где это необходимо.
prepend_to_file() {
file=$1
text=$2
if ! [[ -f $file ]] then
touch $file
fi
echo "$text" | cat - $file > $file.new
mv -f $file.new $file
}
Тогда используйте это так:
prepend_to_file test.txt "This is first"
prepend_to_file test.txt "This is second"
В таком случае содержимое вашего файла будет:
This is second
This is first
Я собираюсь использовать этот подход для реализации средства обновления журнала изменений.