Як вставити текст на початку файлу?


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 означає in-place, ви можете додати суфікс -i, щоб зробити копію, а не перезаписати. -i.new створив би новий файл, що закінчується .new, але просто -i буде редагувати файл безпосередньо.
Джей Камат

3
Зверніть увагу, що sed не буде працювати з порожнім файлом - afaict sed не може взагалі нічого робити при введенні 0-довжини.
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додаванню нової лінії ?
Toby Speight

Я спробував спрямувати це у файл, додавши > fileкоманду, він jus спамерував мій термінал"some text at the beginning"
theonlygusti

2
printf '%s' "some text" | cat - filename > tmpfile && mv tmpfile filename
luca

10

Щоб вставити лише новий рядок:

sed '1i\\'


5

Зауважте, що в OS X sed -i <pattern> file,, не працює. Однак якщо ви надаєте розширення для резервного копіювання sed -i old <pattern> file, тоді fileвоно змінюється на місці, поки file.oldвоно створене. Потім ви можете видалити file.oldзі свого сценарію.


4
Або sed -i '' файл. Тоді він буде просто редагувати на місці, а не робити резервні копії.
Харв

Я знайшов, що 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), і встановити кот, що і файл, щоб темп ... Дивіться також пояснення внизу 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 ...рішення типу).

ДОПОМОГА: 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

Просто для задоволення, ось рішення, за допомогою 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
Чи можете ви пояснити, як це допоможе Томасу в питанні?
Джон Одом

tac | tac - ось так формуються міркування, що не масштабуються :-(
Майкл Шигорін

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.