Bagaimana cara menyisipkan teks di awal file?

213

Sejauh ini saya sudah bisa menemukan cara menambahkan baris di awal file tetapi bukan itu yang saya inginkan. Saya akan menunjukkannya pada contoh

Konten file

some text at the beginning

Hasil

<added text> some text at the beginning

Ini mirip tetapi saya tidak ingin membuat baris baru dengannya ...

Saya ingin melakukan ini dengan sedjika memungkinkan.

pengguna219882
sumber
Adakah yang bekerja di sini untukmu? stackoverflow.com/questions/54365/… - Anda tidak perlu menggunakan sed.
wkl

Jawaban:

314

sed dapat beroperasi pada alamat:

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

Apakah keajaiban ini yang 1sAnda lihat pada setiap jawaban di sini? Mengatasi garis! .

Ingin menambahkan <added text>10 baris pertama?

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

Atau Anda dapat menggunakan Command Grouping:

$ { echo -n '<added text> '; cat file; } >file.new
$ mv file{.new,}
kev
sumber
67
Untuk benar-benar menyisipkan baris baru: sed -i's 1s / ^ / <teks tambahan> \ n / 'file
jslatts
1
Mengapa menggunakan -i ?? Pada manusia dikatakan bahwa itu untuk sufiks. linux.die.net/man/1/sed
endrigoantonini
-I singkatan dari in-place, Anda bisa menambahkan akhiran ke -i untuk membuat salinan alih-alih menimpa. -i.new akan membuat file baru yang diakhiri dengan .new, tetapi hanya -i akan mengedit file secara langsung.
Jay Kamat
3
Perhatikan bahwa sed tidak akan berfungsi pada file kosong - sed sed afaict tidak dapat dilakukan untuk melakukan apa pun dengan input 0 panjang.
jthill
2
Kelemahan dari solusi ini adalah tidak menambah teks jika file kosong.
DBedrenko
41

Jika Anda ingin menambahkan baris di awal file, Anda perlu menambahkan \ndi akhir string dalam solusi terbaik di atas.

Solusi terbaik akan menambahkan string, tetapi dengan string, itu tidak akan menambahkan baris di akhir file.

sed -i '1s/^/your text\n/' file
Ali Reza Ebadat
sumber
27

Jika file hanya satu baris, Anda dapat menggunakan:

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

Jika lebih dari satu baris. satu dari:

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

Saya telah memasukkan yang terakhir sehingga Anda tahu bagaimana melakukan rentang garis. Kedua "ganti" ini penanda garis mulai pada baris yang terpengaruh dengan teks yang ingin Anda masukkan. Anda juga dapat (dengan anggapan Anda sedcukup modern) menggunakan:

sed -i 'whatever command you choose' filename

untuk melakukan pengeditan di tempat.

paxdiablo
sumber
11

Kamu bisa memakai cat -

printf '%s' "some text at the beginning" | cat - filename
Lex
sumber
6
Ini hanya akan menghasilkan teks yang diikuti oleh konten file, tetapi tidak mengubah file sama sekali.
Adaephon
Itu solusi yang bagus, saya bertanya-tanya mengapa itu tidak mendapatkan upvotes. Ini milikku tuanku yang baik. Juga, mengapa printf dan bukan gema sederhana?
ychaouche
1
@ychaouche - mungkin karena tidak ada cara portabel untuk mencegah echopenambahan baris baru?
Toby Speight
Saya mencoba mengarahkan ini ke file dengan menambahkan > fileperintah, itu hanya mem-spammed terminal saya dengan"some text at the beginning"
theonlygusti
2
printf '%s' "some text" | cat - filename > tmpfile && mv tmpfile filename
luca
11

Untuk menyisipkan baris baru:

sed '1i\\'

sumber
Saya bertanya-tanya mengapa jawaban terpilih semua menggunakan s bukan i. Adakah kerugian untuk ini?
Caesar
8

Gunakan subkulit:

echo "$(echo -n 'hello'; cat filename)" > filename
Nick Roz
sumber
5

Perhatikan bahwa pada OS X sed -i <pattern> file,, gagal. Namun, jika Anda memberikan ekstensi cadangan sed -i old <pattern> file,, maka filediubah di tempat saat file.olddibuat. Anda kemudian dapat menghapus file.olddalam skrip Anda.

Curt Clifton
sumber
4
Atau sed-i '' file. Maka itu hanya akan mengedit di tempat dan tidak membuat cadangan.
Harv
Saya telah menemukan macOS dan ingin sebuah titik untuk diedit tanpa membuat cadangan: sed -i. File <pola>
Bryan
4

MASALAH: memberi tag pada file, di bagian atas file, dengan nama dasar direktori induk.

Yaitu, untuk

/mnt/Vancouver/Programming/file1

tandai bagian atas file1dengan Programming.

SOLUSI 1 - file tidak kosong:

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

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

1s menempatkan teks pada baris 1 file.

SOLUSI 2 - file kosong atau tidak kosong:

The sedperintah, atas, gagal pada file kosong. Berikut ini solusinya, berdasarkan /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>

Perhatikan bahwa perintah -di dalam cat diperlukan (baca input standar: lihat man catuntuk informasi lebih lanjut). Di sini, saya percaya, diperlukan untuk mengambil output dari pernyataan printf (ke STDIN), dan cat itu dan file untuk temp ... Lihat juga penjelasan di bagian bawah http://www.linfo.org/cat .html .

Saya juga menambahkan -fke mvperintah, untuk menghindari dimintai konfirmasi ketika menimpa file.

Untuk berulang pada direktori:

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

Perhatikan juga bahwa ini akan memecah jalur dengan spasi; ada solusi, di tempat lain (misalnya file globbing, atau find . -type f ...-type solusi) untuk itu.

ADDENDUM: Re: komentar terakhir saya, skrip ini akan memungkinkan Anda untuk melihat kembali direktori dengan spasi di jalur:

#!/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
Victoria Stuart
sumber
3

Hai dengan carriage return:

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

Untuk menambahkan baris ke bagian atas file:

sed -i '1iText to add\'
solidsnack
sumber
Ini termasuk baris baru, yang tidak diinginkan si penanya secara eksplisit.
Toby Speight
Terima kasih telah memberikan apa yang saya butuhkan
FindOutIslamNow
3

Ada cara yang sangat mudah:

echo "your header" > headerFile.txt
cat yourFile >> headerFile.txt
Raphael Villas Boas
sumber
Ow ... maaf, sekarang saya menyadari bahwa Anda ingin menambahkan di awal dan bukan baris baru.
Raphael Villas Boas
Tapi saya ingin baris baru. Jadi terima kasih atas pendekatan yang sederhana.
TheSatinKnight
3

Hanya untuk bersenang-senang, berikut adalah solusi menggunakan edyang tidak memiliki masalah tidak bekerja pada file kosong. Anda dapat memasukkannya ke dalam skrip shell seperti halnya jawaban lain untuk pertanyaan ini.

ed Test <<EOF
a

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

Script di atas menambahkan teks untuk disisipkan ke baris pertama, dan kemudian bergabung dengan baris pertama dan kedua. Untuk menghindari ed keluar dari kesalahan dengan bergabung tidak valid, itu pertama-tama membuat garis kosong di akhir file dan menghapusnya nanti jika masih ada.

Keterbatasan: Skrip ini tidak berfungsi jika <added text>sama persis dengan satu periode tunggal.

merlin2011
sumber
2

dua sen saya:

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

Ini akan berfungsi bahkan adalah string yang berisi garis miring "/"

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

Yang pertama tacmem-pipe file mundur (baris terakhir terlebih dahulu) sehingga "teks yang akan disisipkan" muncul terakhir. Yang ke-2 tacmembungkusnya sekali lagi sehingga baris yang dimasukkan berada di awal dan file aslinya berada dalam urutan aslinya.

paulp
sumber
1
Bisakah Anda jelaskan bagaimana ini akan membantu Tomas dengan masalah ini?
John Odom
tac | tac - begitulah pola pikir non-scalable terbentuk :-(
Michael Shigorin
0

Solusi lain dengan alias. Tambahkan ke file rc / env init Anda:

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

Pemakaian:

addtail "string to add at the beginning of file"
addtail "string to add at the end of file"
0x8BADF00D
sumber