Unix команда для добавления текста в файл

Есть ли команда Unix для добавления некоторых строковых данных в текстовый файл?

Что-то вроде:

prepend "to be prepended" text.txt

22 ответа

Решение
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


Здесь Строка

Используя здесь-строку - <<< (опять же, вам нужен bash), вы можете сделать:

<<< "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

Если допустимо заменить входной файл:

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

sed -iКак и в ответе принца Джона Уэсли, пытается хотя бы восстановить исходные разрешения, но применяются другие ограничения.

 { printf 'line 1\nline 2\n'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt

Примечание. Использование групповой команды. { ...; ... } более эффективно, чем использование subshell ((...; ...)).


Если входной файл должен быть отредактирован на месте (сохраняя его inode со всеми его атрибутами):

Используя почтенный ed Утилита POSIX:

Замечания: ed неизменно сначала считывает входной файл целиком в память.

ed -s text.txt <<'EOF' 
1i
line 1
line 2
.
w
EOF
  • -s подавленный edстатусные сообщения.
  • Обратите внимание, как команды предоставляются ed как многострочный документ здесь (<<'EOF' ... EOF), т.е. через стандартный ввод.
  • 1i марки 1 (1-я строка) текущей строки и запускает режим вставки (i).
  • Следующие строки представляют собой текст для вставки перед текущей строкой, оканчивающийся на . на своей собственной линии.
  • w записывает результат обратно во входной файл (для тестирования заменить w с ,p только для печати результата, без изменения входного файла).

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

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

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

echo "to be prepended" | cat - text.txt | tee text.txt

Если вы хотите опустить tee вывод, затем добавьте > /dev/null,

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

#!/bin/bash
echo -n "$1" > /tmp/tmpfile.$$
cat "$2" >> /tmp/tmpfile.$$
mv /tmp/tmpfile.$$ "$2"

Нечто подобное по крайней мере...

Решение:

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)", Все обходные пути для этого являются относительно сложными. Если вы хотите сохранить символы новой строки в конце file.txt, посмотрите это: /questions/2313984/kak-prochitat-fajl-v-peremennuyu-v-obolochke/2314008#2314008

Еще один способ использования 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)

Вы можете легко это сделать с помощью awk

      cat text.txt|awk '{print "to be prepended"$0}'
      % echo blaha > blaha
% echo fizz > fizz
% cat blaha fizz > buzz
% cat buzz 
blaha
fizz

Если вам нравится vi/vim, это может быть больше вашего стиля.

printf '0i\n%s\n.\nwq\n' prepend-text | ed file

С ,

      ex - $file << PREPEND
-1
i
prepended text
.
wq
PREPEND

The exкоманды

  • -1Перейти в самое начало файла
  • iНачать режим вставки
  • .Завершить режим вставки
  • wqСохранить (записать) и выйти

Для будущих читателей, которые хотят добавить одну или несколько строк текста (с переменными или даже кодом подоболочки) и сохранить его читабельным и отформатированным, вам может понравиться следующее:

      echo "Lonely string" > my-file.txt

Тогда беги

      cat <<EOF > my-file.txt
Hello, there!

$(cat my-file.txt)
EOF

Результаты cat my-file.txt:

      Hello, there!

Lonely string

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

вы можете использовать переменные

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

      PREPEND="new line 1"; FILE="text.txt"; printf "${PREPEND}\n`cat $FILE`" > $FILE

В этом фрагменте просто заменитеtext.txtс текстовым файлом, который вы хотите добавить в начало, иnew line 1с текстом для начала.

пример

      $ printf "old line 1\nold line 2" > text.txt
$ cat text.txt; echo ""
old line 1
old line 2
$ PREPEND="new line 1"; FILE="text.txt"; printf "${PREPEND}\n`cat $FILE`" > $FILE 
$ cat text.txt; echo ""
new line 1
old line 1
old line 2
$

Мне не очень понравились какие-либо ответы здесь, поэтому я создал свою собственную команду: pre,

Установите с go:

go get -u github.com/Flaque/pre

Добавьте текст из stdin в файл с помощью:

echo "some at the start" | pre myFile.txt | sponge myFile.txt

Команда не записывается на месте, она просто выводит на стандартный вывод, поэтому вам понадобится sponge от moreutils в конце, чтобы сохранить файл.

Я бы рекомендовал определить функцию, а затем импортировать и использовать ее там, где это необходимо.

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

Я собираюсь использовать этот подход для реализации средства обновления журнала изменений.

# 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
Другие вопросы по тегам