Вопрос: Как добавить текст в начало файла в Bash?


Привет, я хочу добавить текст в файл. Например, я хочу добавить задачи в начало файла todo.txt. Я знаю о echo 'task goes here' >> todo.txt но это добавляет строку в конец файла (не то, что я хочу).


228
2018-02-17 03:21


Источник


Там, где нет эффективного способа сделать это для больших файлов: unix.stackexchange.com/questions/87772/... - Ciro Santilli 新疆改造中心 六四事件 法轮功


Ответы:


echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt

или

sed -i '1s/^/task goes here\n/' todo.txt

или

sed -i '1itask goes here' todo.txt

303
2018-02-17 03:34



первый работает отлично! не могли бы вы объяснить логику? im не особо уверен, как интерпретировать синтаксис. - user479534
@ user8347: Труба (|) сообщение (echo '...') до cat который использует - (стандартный ввод) в качестве первого файла и todo.txt как второй. cat conCATenate несколько файлов. Отправлять вывод (>) в файл с именем temp, Если ошибок нет (&&) из cat затем переименуйте (mv) temp вернуться к исходному файлу (todo.txt). - Dennis Williamson
Я не знал об этом возможном синтаксисе в последнем примере sed, может ли кто-нибудь сказать мне, что такое имя этого типа синтаксиса, чтобы я мог больше узнать об этом? - Kira
@Kira: 1 означает следующую команду только в строке 1 файла и i команда - вставка. Посмотрите на странице руководства в разделе «Адреса» и в разделе «Команды нуля или одного адреса». - Dennis Williamson
@Terrance: Если ваш sed команда выглядит примерно так (вставка ведущей вкладки): '1i\tSome Text', вам может потребоваться удвоить обратную косую черту. В противном случае ваш диалект sed может не признать \t как вкладка. - Dennis Williamson


На мой взгляд, более простой вариант:

echo -e "task goes here\n$(cat todo.txt)" > todo.txt

Это работает, потому что команда внутри $(...) выполняется до todo.txt перезаписывается > todo.txt

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

РЕДАКТИРОВАТЬ: Это решение - очень плохая идея, если есть какие-либо обратные косые черты в todo.txt, поскольку благодаря -e flag echo будет их интерпретировать. Другой, гораздо более простой способ получить символы новой строки в строке предисловия ...

echo "task goes here
$(cat todo.txt)" > todo.txt

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

(echo 'task goes here' && cat todo.txt) > todo.txt
echo 'task goes here'$'\n'"$(cat todo.txt)" > todo.txt

Кроме того, если вам интересно, добавляется ли новая строка в конец todo.txt, не используйте их. Ну, кроме второго до последнего. Это не путается с концом.


59
2017-12-19 18:57



Я вообще не получаю $ (...). - SCL
Это может работать лучше (или вообще) с двойными кавычками вместо одного ... - ℝaphink
Не будет -e также конвертировать escape-последовательности внутри todo.txt? - mk12
Обходные пути -> cat: <имя_файла назначения>: входной файл - это выходной файл ... - ingyhere
printf будет намного более согласованным между платформами и, как правило, будет работать более плавно, чем echo -e - Peter Berg


moreutils иметь хороший инструмент под названием sponge:

echo "task goes here" | cat - todo.txt | sponge todo.txt

Он будет «впитывать» STDIN, а затем записывать в файл, что означает, что вам не нужно беспокоиться о временных файлах и перемещать их.

Вы можете получить moreutils со многими дистрибутивами Linux, через apt-get install moreutils, или на OS X, используя Homebrew, с brew install moreutils,


26
2018-04-22 12:47





Вы можете использовать Vim в режиме Ex:

ex -sc '1i|task goes here' -cx todo.txt
  1. 1 выберите первую строку

  2. i вставить

  3. x сохрани и закрой


5
2018-04-11 00:23





Вы можете создать новый временный файл.

echo "new task" > new_todo.txt
cat todo.txt >> new_todo.txt
rm todo.txt
mv new_todo.txt todo.txt

Вы также можете использовать sed или awk, Но в основном то же самое происходит.


3
2018-02-17 03:26



Скажите, что вы вне места на диске, чтобы new_todo.txt записывается только частично. Ваше решение потеряет исходный файл. - NPE
У кого заканчивается дисковое пространство? ;-) Это просто простой пример. - Keith
@Keith Кто-то работает над виртуальной машиной, которая не ожидала особого виртуального диска. Или кто-то перемещает большой файл. В любом случае, реальный аргумент против этого - права доступа к каталогам; если у вас нет разрешения на создание новых файлов в данном каталоге, единственная команда, которая будет успешно выполнена в вашем скрипте, - это rm исходного файла. - Parthian Shot


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

echo "$(echo 'task goes here' | cat - todo.txt)" > todo.txt

Невозможно добавить строки в начало файла без написания всего файла.


3
2018-01-09 22:49



Просто чтобы задать очевидный вопрос: Где предел символов переменных оболочки? - nixda
Насколько мне известно, он ограничен только объемом доступной памяти. Я заполнил переменные размером более 100 МБ в памяти. text=$(cat file), Будьте осторожны, чтобы использовать только текст, потому что переменные оболочки не являются бинарными mywiki.wooledge.org/BashFAQ/058 - Rucent88


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

Тогда любое решение вашего вопроса требует создания временного файла (или буфера) (в памяти или на диске), который в конечном итоге перезапишет исходный файл.

Остерегайтесь не потерять данные, сохранив исходный файл при создании нового, если файловая система окажется заполненной во время процесса. например:

cat <(echo task go there) todo.txt > todo.txt.new && mv todo.txt.new todo.txt

2
2018-02-17 06:25



Доводчики могут объяснить свою мотивацию. Ни один из оставшихся ответов, в том числе принятый, в моем ответе ничего не противоречит. - jlliagre
Это трудно разобрать, поскольку <...> выглядят как скобки, которые, как я полагаю, они не являются. Пробел между <и (может помочь? - dumbledad
Это не работает для меня. echo HOME=\"/g/Users/timregan/\" | cat - 'F:\Program Files\Git\etc\profile' работает, но cat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile' дает ошибку "echo: Нет такого файла или каталога" - dumbledad
@dumbledad Ты перевыполняешь мой ответ. Вам нечего разбираться в этом. Пространство между < и ( нарушит синтаксис. Пытаться cat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile' - jlliagre


Вы можете использовать tee:

echo 'task goes here' | cat - todo.txt | tee todo.txt

1
2017-07-08 14:16



Нет, ты не можешь askubuntu.com/a/752451 - Steven Penny


GitBash + Windows 10 + Multline:

Вот версия, которая позволяет использовать многострочные строки,

##############################################
## This section for demo purpose only,      ##
## So you can save entire file as           ##
## whatever.sh and run it.                  ##
##                                          ##
##############################################
> MY_TARGET_FILE.txt ##Make Or Clear File
echo "[STARTER_CONTENT]" >> MY_TARGET_FILE.txt
##############################################

## Below is main code:

##################################################
TARGET_FILE_VARIABLE="MY_TARGET_FILE.txt"
ADD_TO_HEAD_VARIABLE=$(cat << "HEREDOC_HEAD_TEXT"
//|  +-------------------------------------+   |//
//|  |                                     |   |//
//|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
//|  |                                     |   |//
//|  +-------------------------------------+   |//
HEREDOC_HEAD_TEXT
)
##################################################
TAR=$TARGET_FILE_VARIABLE                       ##
TEX=$ADD_TO_HEAD_VARIABLE                       ##
echo "$TEX" | cat - $TAR > TEMP && mv TEMP $TAR ##
##################################################

## Expected contents of MY_TARGET_FILE.txt :
## //|  +-------------------------------------+   |//
## //|  |                                     |   |//
## //|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
## //|  |                                     |   |//
## //|  +-------------------------------------+   |//
## [STARTER_CONTENT]

0
2017-08-04 07:04