Unix: как я могу добавить вывод в файл? - PullRequest
13 голосов
/ 18 октября 2011

В частности, я использую комбинацию >> и tee в пользовательском псевдониме для хранения новых обновлений Homebrew в текстовом файле, а также для вывода на экран:

alias bu="echo `date "+%Y-%m-%d at %H:%M"` \
    >> ~/Documents/Homebrew\ Updates.txt && \
    brew update | tee -a ~/Documents/Homebrew\ Updates.txt"

Вопрос : Что если я захочу добавить этот вывод в мой текстовый файл, т.е. поместить его в начало файла, а не добавлять его в конец?


Edit1 : Как кто-то сообщил в ответах ниже, использование временных файлов может быть хорошим подходом, который, по крайней мере, помог мне частично:

targetLog="~/Documents/Homebrew\ Updates.txt"
alias bu="(brew update | cat - $targetLog \
> /tmp/out1 && mv /tmp/out1 $targetLog \
&& echo `date "+%Y-%m-%d at %H:%M":%S` | \
cat - $targetLog > /tmp/out2 \
&& mv /tmp/out2 $targetLog)"

Но проблема заключается в выводев STDOUT (ранее стало возможным благодаря tee), который, я не уверен, может быть включен в этот подход к временным файлам…?

Ответы [ 6 ]

13 голосов
/ 18 октября 2011

sed с радостью сделает это за вас, используя -i для редактирования на месте, например.

sed -i -e "1i `date "+%Y-%m-%d at %H:%M"`" some_file
8 голосов
/ 22 июля 2014

Это работает путем создания выходного файла:

Допустим, у нас есть начальное содержимое файла file.txt

echo "first line" > file.txt          
echo "second line" >> file.txt

Итак, file.txt - это наш «нижний» текстовый файл. Теперь добавьте новый файл вывода

echo "add new first line" | cat - file.txt > output.txt # <--- Just this command

Теперь вывод имеет содержимое так, как мы хотим. Если вам нужно ваше старое имя:

mv output.txt file.txt
cat file.txt
3 голосов
/ 18 октября 2011

Единственный простой и безопасный способ изменить входной файл с помощью инструментов bash - это использовать временный файл, например. sed -i использует временный файл за кулисами (но для устойчивости sed нужно больше).

Некоторые из используемых методов имеют тонкую ловушку «может сломать вещи», когда вместо запуска команды в файле данных real вы запускаете его по символической ссылке (в файл, который вы собираетесь изменить). Если не принять правильное решение, это может привести к разрыву ссылки и преобразованию ее в настоящий файл, который получает моды и оставляет оригинальный настоящий файл без намеченных модов и без символической ссылки (без ошибок результаты кода выхода)

Чтобы избежать этого с sed, вам нужно использовать опцию --follow-symlinks.
Для других методов, просто имейте в виду, что он должен следовать символическим ссылкам (когда вы действуете по такой ссылке)
Используя временный файл, rm temp file работает, только если «файл» не является символической ссылкой.

Один безопасный способ - использовать sponge из пакета moreutils

В отличие от перенаправления оболочки, губка впитывает весь свой ввод перед открытие выходной файл. Это позволяет строить конвейеры, которые читают из и записать в тот же файл.

sponge - это хороший общий способ справиться с такой ситуацией.

Вот пример использования sponge

hbu=~/'Documents/Homebrew Updates.txt'
{ date "+%Y-%m-%d at %H:%M"; cat "$hbu"; } | sponge "$hbu"
2 голосов
/ 18 октября 2011

Простейшим способом IMO было бы использовать echo и cat:

echo "Prepend" | cat - inputfile > outputfile

Или для вашего примера, в основном, заменить tee -a ~/Documents/Homebrew\ Updates.txt на cat - ~/Documents/Homebrew\ Updates.txt > ~/Documents/Homebrew\ Updates.txt

Редактировать: как сказано в hasturkunне получится, попробуйте:

echo "Prepend" | cat - file | tee file

Но это уже не самый эффективный способ сделать это ...

1 голос
/ 19 октября 2011
{ date; brew update |tee /dev/tty; cat updates.txt; } >updates.txt.new
mv updates.txt.new updates.txt

Я понятия не имею, почему вы хотите это сделать. Это довольно стандартно, что журналы, подобные этой, имеют более поздние записи, которые появляются в файле позже.

1 голос
/ 18 октября 2011

Попробуйте это http://www.unix.com/shell-programming-scripting/42200-add-text-beginning-file.html Нет прямого оператора или команды AFAIK. Вы используете echo, cat и mv для получения эффекта.

...