Как вставить текст в начале файла?


213

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

Содержание файла

some text at the beginning

результат

<added text> some text at the beginning

Это похоже, но я не хочу создавать новую линию с этим ...

Я хотел бы сделать это с, sedесли это возможно.


Что-нибудь здесь работает для вас? stackoverflow.com/questions/54365/… - вам не нужно использовать sed.
WKL

Ответы:


314

sed может работать по адресу:

$ sed -i '1s/^/<added text> /' file

Что это за волшебство 1sвы видите на каждом ответе здесь? Линия адресации! ,

Хотите добавить <added text>в первые 10 строк?

$ sed -i '1,10s/^/<added text> /' file

Или вы можете использовать Command Grouping:

$ { echo -n '<added text> '; cat file; } >file.new
$ mv file{.new,}

67
Чтобы фактически вставить новую строку: sed -i '1s / ^ / <добавленный текст> \ n /' файл
jslatts

1
Зачем использовать -i ?? На мужчине написано, что это суффикс. linux.die.net/man/1/sed
endrigoantonini

-i означает на месте, вы можете добавить суффикс -i, чтобы сделать копию, а не перезаписать. -i.new создаст новый файл, заканчивающийся на .new, но просто -i отредактирует файл напрямую.
Джей Камат

3
Обратите внимание, что sed не будет работать с пустым файлом - afaict sed не может вообще ничего делать с вводом нулевой длины.
jthill

2
Недостатком этого решения является то, что оно не добавляет текст, если файл пуст.
Д.Бедренко

41

Если вы хотите добавить строку в начале файла, вам нужно добавить \nв конце строки лучшее решение, описанное выше.

Лучшее решение - добавить строку, но со строкой она не добавит строку в конец файла.

sed -i '1s/^/your text\n/' file

27

Если файл содержит только одну строку, вы можете использовать:

sed 's/^/insert this /' oldfile > newfile

Если это более одной строки. один из:

sed '1s/^/insert this /' oldfile > newfile
sed '1,1s/^/insert this /' oldfile > newfile

Я включил последний, чтобы вы знали, как делать диапазоны линий. Оба из них «заменяют» маркер начальной строки на соответствующих строках текстом, который вы хотите вставить. Вы также можете (при условии, что вы sedдостаточно современны) использовать:

sed -i 'whatever command you choose' filename

сделать редактирование на месте.


11

Ты можешь использовать cat -

printf '%s' "some text at the beginning" | cat - filename

6
Это только вывело бы текст, сопровождаемый содержанием файла, но это не изменяет файл вообще.
Adaephon

Это хорошее решение, мне интересно, почему оно не получило никаких голосов. Вот мой мой хороший сэр. Кроме того, почему printf, а не простое эхо?
ychaouche

1
@ychaouche - возможно потому что нет переносимого способа запретить echoдобавление новой строки?
Тоби Спейт

Я попытался направить это в файл, добавив > fileк команде, он просто спамил мой терминал с"some text at the beginning"
theonlygusti

2
printf '%s' "some text" | cat - filename > tmpfile && mv tmpfile filename
Лука

11

Чтобы вставить только новую строку:

sed '1i\\'

Интересно, почему в топ-ответах все используют s вместо i. Есть ли минусы к этому?
Цезарь


5

Обратите внимание, что на OS X sed -i <pattern> file, не удается. Однако, если вы предоставите расширение для резервной копии sed -i old <pattern> file, оно fileбудет изменено на месте, пока file.oldсоздается. Затем вы можете удалить file.oldв своем скрипте.


4
Или файл sed -i ''. Тогда он будет просто редактировать на месте, а не делать резервные копии.
Harv

Я обнаружил, что macOS sed хочет редактировать точку без создания резервной копии: sed -i. Файл <pattern>
Брайан,

4

ПРОБЛЕМА: пометьте файл в верхней части файла базовым именем родительского каталога.

То есть для

/mnt/Vancouver/Programming/file1

пометить верх file1с Programming.

РЕШЕНИЕ 1 - непустые файлы:

bn=${PWD##*/}    ## bn: basename

sed -i '1s/^/'"$bn"'\n/' <file>

1s помещает текст в строку 1 файла.

РЕШЕНИЕ 2 - пустые или непустые файлы:

Команда sedвыше, терпит неудачу на пустых файлах. Вот решение, основанное на /superuser/246837/how-do-i-add-text-to-the-beginning-of-a-file-in-bash/246841#246841

printf "${PWD##*/}\n" | cat - <file> > temp && mv -f temp <file>

Обратите внимание, что -требуется команда in cat (читает стандартный ввод: см. man catДополнительную информацию). Здесь, я полагаю, необходимо взять выходные данные оператора printf (в STDIN), а затем преобразовать его и файл в temp ... См. Также пояснение внизу http://www.linfo.org/cat .html .

Я также добавил -fв mvкоманду, чтобы не запрашивать подтверждения при перезаписи файлов.

Чтобы выполнить поиск по каталогу:

for file in *; do printf "${PWD##*/}\n" | cat - $file > temp && mv -f temp $file; done

Также обратите внимание, что это сломает пути с пробелами; для них есть решения, в другом месте (например, глобализация файлов или find . -type f ...решения типа).

ADDENDUM: Re: мой последний комментарий, этот скрипт позволит вам просматривать каталоги с пробелами в путях:

#!/bin/bash

## /programming/4638874/how-to-loop-through-a-directory-recursively-to-delete-files-with-certain-extensi

## To allow spaces in filenames,
##   at the top of the script include: IFS=$'\n'; set -f
##   at the end of the script include: unset IFS; set +f

IFS=$'\n'; set -f

# ----------------------------------------------------------------------------
# SET PATHS:

IN="/mnt/Vancouver/Programming/data/claws-test/corpus test/"

# /superuser/716001/how-can-i-get-files-with-numeric-names-using-ls-command

# FILES=$(find $IN -type f -regex ".*/[0-9]*")        ## recursive; numeric filenames only
FILES=$(find $IN -type f -regex ".*/[0-9 ]*")         ## recursive; numeric filenames only (may include spaces)

# echo '$FILES:'                                      ## single-quoted, (literally) prints: $FILES:
# echo "$FILES"                                       ## double-quoted, prints path/, filename (one per line)

# ----------------------------------------------------------------------------
# MAIN LOOP:

for f in $FILES
do

  # Tag top of file with basename of current dir:
  printf "[top] Tag: ${PWD##*/}\n\n" | cat - $f > temp && mv -f temp $f

  # Tag bottom of file with basename of current dir:
  printf "\n[bottom] Tag: ${PWD##*/}\n" >> $f
done

unset IFS; set +f

3

Привет с возвратом каретки:

sed -i '1s/^/your text\n/' file

3

Чтобы добавить строку в начало файла:

sed -i '1iText to add\'

Это включает в себя новую строку, которую спрашивающий явно не хочет.
Тоби Спейт

Спасибо, что дали мне именно то, что мне нужно
FindOutIslamNow

3

Есть очень простой способ:

echo "your header" > headerFile.txt
cat yourFile >> headerFile.txt

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

Но я хотел новую линию. Так что спасибо за упрощенный подход.
TheSatinKnight

3

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

ed Test <<EOF
a

.
0i
<added text>
.
1,+1 j
$ g/^$/d
wq
EOF

Приведенный выше скрипт добавляет текст для вставки в первую строку, а затем соединяет первую и вторую строки. Чтобы избежать выхода при ошибке с недопустимым соединением, сначала создается пустая строка в конце файла, а затем удаляется, если он все еще существует.

Ограничения: этот скрипт не работает, если <added text>он точно равен одному периоду.


2

мои два цента:

sed  -i '1i /path/of/file.sh' filename

Это будет работать, даже если строка содержит косую черту "/"


1
echo -n "text to insert " ;tac filename.txt| tac > newfilename.txt

Первая tacнаправляет файл назад (последняя строка первая), поэтому «текст для вставки» появляется последним. 2-й tacпереносит его еще раз, поэтому вставленная строка находится в начале, а исходный файл - в исходном порядке.


1
Не могли бы вы объяснить, как это поможет Томасу в решении этой проблемы?
Джон Одом

так | так - так формируются немасштабируемые установки мышления :-(
Михаил Шигорин

0

Еще одно решение с псевдонимами. Добавьте в ваш файл init rc / env:

addtail () { find . -type f ! -path "./.git/*" -exec sh -c "echo $@ >> {}" \; }
addhead () { find . -type f ! -path "./.git/*" -exec sh -c  "sed -i '1s/^/$@\n/' {}" \; }

Использование:

addtail "string to add at the beginning of file"
addtail "string to add at the end of file"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.