Ответ 1
sed с радостью сделает это за вас, используя -i
для редактирования на месте, например.
sed -i -e "1i `date "+%Y-%m-%d at %H:%M"`" some_file
В частности, я использую комбинацию >>
и 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), который я не уверен, может быть включен в этот подход tempfile...?
sed с радостью сделает это за вас, используя -i
для редактирования на месте, например.
sed -i -e "1i `date "+%Y-%m-%d at %H:%M"`" some_file
Это работает, создавая выходной файл:
Скажем, у нас есть начальное содержимое файла file.txt
echo "first line" > file.txt
echo "second line" >> file.txt
Итак, file.txt - это наш "нижний" текстовый файл. Теперь добавьте новый файл 'output'
echo "add new first line" | cat - file.txt > output.txt # <--- Just this command
Теперь выход имеет содержимое так, как мы хотим. Если вам нужно ваше старое имя:
mv output.txt file.txt
cat file.txt
Единственный простой и безопасный способ изменения входного файла с помощью инструментов bash - использовать временный файл, например. sed -i
использует временный файл за кулисами (но для надежного sed
требуется больше).
Некоторые из используемых методов имеют тонкую ловушку "может сломать вещи", когда вместо запуска вашей команды в реальном файле данных вы запускаете ее по символической ссылке (в файл, который вы собираетесь изменить). Если это не правильно, это может сломать ссылку и преобразовать ее в реальный файл, который получает моды и оставляет исходный реальный файл без предполагаемых модов и без символической ссылки (без ошибок выхода из кода)
Чтобы избежать этого с помощью 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"
Простейшим способом ИМО было бы использовать эхо и кошку:
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
Но это не самый эффективный способ сделать это больше...
Попробуйте http://www.unix.com/shell-programming-scripting/42200-add-text-beginning-file.html Прямого оператора или команды AFAIK нет. Для получения эффекта используйте эхо, cat и mv.
{ date; brew update |tee /dev/tty; cat updates.txt; } >updates.txt.new
mv updates.txt.new updates.txt
Я не знаю, почему вы хотите это сделать. Это довольно стандартно, что в таких журналах появляются более поздние записи, ну, в дальнейшем в файле.