Unix команды для добавления текста в файл
есть ли команда Unix для добавления некоторых строковых данных в текстовый файл?
что-то типа:
prepend "to be prepended" text.txt
16 ответов:
sed -i.old '1s;^;to be prepended;' inFile
-i
записывает изменение на месте и создает резервную копию, если задано какое-либо расширение. (В данном случае.old
)1s;^;to be prepended;
заменяет начало первой строки заданной строкой замены, используя;
как разделитель команд.
Это одна из возможностей:
(echo "to be prepended"; cat text.txt) > newfile.txt
вы, вероятно, не так легко обойти промежуточный файл.
альтернативы (могут быть громоздкими с выходом оболочки):
sed -i '0,/^/s//to be prepended/' text.txt
Подмена Процесса
Я удивлен, что никто не упомянул об этом.
cat <(echo "before") text.txt > newfile.txt
что, возможно, более естественно, чем принятый ответ (печать чего-то и передача его в команду замены лексикографически противоречит интуиции).
...и захватить то, что Райан сказал выше, с
sponge
вам не нужен временный файл:sudo apt-get install moreutils <<(echo "to be prepended") < text.txt | sponge text.txt
EDIT: похоже, это не работает в Bourne Shell
/bin/sh
здесь Строка
используя здесь-строку -
<<<
(опять же, вам нужно Баш), вы можете сделать:<<< "to be prepended" < text.txt | sponge 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 "" > /tmp/tmpfile.$$ cat "" >> /tmp/tmpfile.$$ mv /tmp/tmpfile.$$ ""
что-то вроде этого, по крайней мере...
в некоторых случаях прилагаемый текст может быть доступен только из stdin. Тогда эта комбинация должна работать.
echo "to be prepended" | cat - text.txt | tee text.txt
Если вы хотите опустить
tee
выход, затем добавить> /dev/null
.
если это приемлемо для заменить входной файл:
Примечание: делать так может иметь неожиданные побочные эффекты, в частности замена символьной ссылки на обычный файл, возможно, в конечном итоге с различными разрешениями на файл, и изменение даты создания (рождения) файла.
sed -i
, а в ответ Принца Джона Уэсли, пытается хотя бы восстановить исходные разрешения, но применяются и другие ограничения.{ printf 'line 1\nline 2\n'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt
Примечание: с помощью группа команда
{ ...; ... }
является более эффективным, чем использование subshell ((...; ...)
).
если входной файл должен быть отредактирован на месте (сохраняя свой индекс со всеми его атрибутами):
используя почтенный
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
только print результат, без изменения входного файла).
устранение:
printf '%s\n%s' 'text to prepend' "$(cat file.txt)" > file.txt
обратите внимание, что это безопасно на всех видах входов, потому что нет никаких расширений. Например, если вы хотите вставить
!@#$%^&*()ugly text\n\t\n
он будет просто работать:printf '%s\n%s' '!@#$%^&*()ugly text\n\t\n' "$(cat file.txt)" > file.txt
последняя часть, оставшаяся для рассмотрения, - это удаление пробелов в конце файла во время замены команды
"$(cat file.txt)"
. Все обходные пути для этого относительно сложны. Если вы хотите сохранить новые строки в конце файла.txt, смотрите это: https://stackoverflow.com/a/22607352/1091436
другой способ использования
sed
:sed -i.old '1 {i to be prepended }' inFile
если строка, которая должна быть добавлена, является многострочной:
sed -i.old '1 {i\ to be prepended\ multiline }' inFile
Если вам нравится 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
мне действительно не понравился ни один из ответов здесь, поэтому я построил свою собственную команду:
pre
.установить с go:
go get -u github.com/Flaque/pre
вставить текст из stdin в файл с:
echo "some at the start" | pre myFile.txt | sponge myFile.txt
команда не пишет на месте, она просто выводит на stdout, поэтому вам понадобится
sponge
Сmoreutils
в конце, чтобы сохранить файл.
Я бы рекомендовал определить функцию, а затем импортировать и использовать ее там, где это необходимо.
prepend_to_file() { file= text= 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
Я собираюсь использовать этот подход для реализации изменений обновления журнала.