Оболочка один лайнер, чтобы подготовить к файлу - PullRequest
124 голосов
/ 10 сентября 2008

Это, вероятно, комплексное решение .

Я ищу простой оператор, такой как ">>", но для добавления.

Боюсь, его не существует. Я должен сделать что-то вроде

 mv myfile tmp
 cat myheader tmp > myfile

Что-нибудь умнее?

Ответы [ 32 ]

1 голос
/ 01 октября 2010
sed -i -e "1s/^/new first line\n/" old_file.txt
1 голос
/ 29 июня 2015

Решение с printf:

new_line='the line you want to add'
target_file='/file you/want to/write to'

printf "%s\n$(cat ${target_file})" "${new_line}" > "${target_file}"

Вы также можете сделать:

printf "${new_line}\n$(cat ${target_file})" > "${target_file}"

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

1 голос
/ 05 января 2014

С помощью $ (команда) вы можете записать вывод команды в переменную. Я сделал это тремя командами в одной строке и без временного файла.

originalContent=$(cat targetfile) && echo "text to prepend" > targetfile && echo "$originalContent" >> targetfile
1 голос
/ 13 октября 2014

Если у вас большой файл (в моем случае несколько сотен килобайт) и доступ к python, это намного быстрее, чем cat pipe pipe:

python -c 'f = "filename"; t = open(f).read(); open(f, "w").write("text to prepend " + t)'

0 голосов
/ 29 декабря 2012

Я думаю, что это самый чистый вариант ed:

cat myheader | { echo '0a'; cat ; echo -e ".\nw";} | ed myfile

как функция:

function prepend() { { echo '0a'; cat ; echo -e ".\nw";} | ed $1; }

cat myheader | prepend myfile
0 голосов
/ 05 июня 2015

Быстро и грязно, буферизируем все в памяти с помощью python:

$ echo two > file
$ echo one | python -c "import sys; f=open(sys.argv[1]).read(); open(sys.argv[1],'w').write(sys.stdin.read()+f)" file
$ cat file
one
two
$ # or creating a shortcut...
$ alias prepend='python -c "import sys; f=open(sys.argv[1]).read(); open(sys.argv[1],\"w\").write(sys.stdin.read()+f)"'
$ echo zero | prepend file
$ cat file
zero
one
two
0 голосов
/ 11 сентября 2008

Если вы пишете скрипты на BASH, на самом деле вы можете просто выполнить:

cat - yourfile  /tmp/out && mv /tmp/out yourfile

Это на самом деле в сложном примере, который вы сами разместили в своем собственном вопросе.

0 голосов
/ 16 августа 2014

ИМХО, нет решения оболочки (и никогда не будет), которое бы работало согласованно и надежно независимо от размеров двух файлов myheader и myfile. Причина в том, что если вы хотите сделать это, не возвращаясь к временному файлу (и не позволяя оболочке молча возвращаться во временный файл, например, через такие конструкции, как exec 3<>myfile, конвейерную передачу к tee и т. Д.

«Настоящее» решение, которое вы ищете, должно работать с файловой системой, поэтому оно недоступно в пространстве пользователя и будет зависеть от платформы: вы запрашиваете изменение используемого указателя файловой системы с помощью myfile для текущее значение указателя файловой системы для myheader и замените в файловой системе EOF из myheader связанной ссылкой на текущий адрес файловой системы, на который указывает myfile. Это не тривиально и, очевидно, не может быть сделано не суперпользователем, и, вероятно, не суперпользователем ... Играть с инодами и т. Д.

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

0 голосов
/ 28 апреля 2010
current=`cat my_file` && echo 'my_string' > my_file && echo $current >> my_file

где «my_file» - это файл, к которому нужно добавить «my_string».

0 голосов
/ 13 августа 2011

Мне нравится @ fluffle's ed подход лучший. В конце концов, переключатели командной строки любого инструмента по сравнению с командами редактора сценариев, по сути, здесь одно и то же; не вижу, что в скриптовом редакторе "чистота" немного ниже или меньше.

Вот мой однострочный текст, добавленный к .git/hooks/prepare-commit-msg для добавления файла in-repo .gitmessage для фиксации сообщений:

echo -e "1r $PWD/.gitmessage\n.\nw" | ed -s "$1"

Пример .gitmessage:

# Commit message formatting samples:
#       runlevels: boot +consolekit -zfs-fuse
#

Я делаю 1r вместо 0r, потому что это оставит пустую строку готовности к записи поверх файла из исходного шаблона. Не ставьте пустую строку поверх вашего .gitmessage, в результате вы получите две пустые строки. -s подавляет вывод диагностической информации под ред.

В связи с этим я обнаружил , что для vim-buffs также хорошо иметь:

[core]
        editor = vim -c ':normal gg'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...