Di Bash, bagaimana cara menambahkan string setelah setiap baris dalam file?

112

Bagaimana cara menambahkan string setelah setiap baris dalam file menggunakan bash? Bisakah itu dilakukan dengan menggunakan perintah sed, jika demikian bagaimana?

Jason Volkoz
sumber

Jawaban:

188

Jika Anda sedmengizinkan pengeditan di tempat melalui -iparameter:

sed -e 's/$/string after each line/' -i filename

Jika tidak, Anda harus membuat file sementara:

typeset TMP_FILE=$( mktemp )

touch "${TMP_FILE}"
cp -p filename "${TMP_FILE}"
sed -e 's/$/string after each line/' "${TMP_FILE}" > filename
Tom DeGisi
sumber
Mengapa Anda touchfile sementara? Dan saya akan membuat sedperintah bersyarat pada keberhasilan cpatau yang asli bisa hilang.
Dijeda sampai pemberitahuan lebih lanjut.
Saya menyentuh file tersebut untuk segera menyimpan nama sementara. Ini mungkin tidak diperlukan. Saya pikir Anda benar tentang membuat perintah sed tergantung pada keberhasilan cp. Mengapa tidak mengedit kode untuk memperbaikinya. Saya tidak akan keberatan sedikit pun! Hormat saya, Tom
Tom DeGisi
Bagaimana dengan menambahkan string sebelum baris?
Oxwivi
10
@Oxwivi: sed -e 's/^/string after each line/' -i filename $ berarti akhir baris. ^ berarti awal baris.
Tom DeGisi
Jika saya menyalurkan ke sed, sed 's/^/string after each line/'melakukan apa yang saya harapkan (ditambahkan ke setiap baris) tetapi sed 's/^/string after each line/'tidak (menggantikan seluruh baris dengan string tambahan saya). Apa yang memberi? Ada ide @TomDeGisi?
philadams
17

Saya lebih suka menggunakan awk. Jika hanya ada satu kolom, gunakan $0, jika tidak ganti dengan kolom terakhir.

Satu arah,

awk '{print $0, "string to append after each line"}' file > new_file

atau ini,

awk '$0=$0"string to append after each line"' file > new_file
Optimus prime
sumber
1
Juga, untuk menambahkan nomor baris (seperti dalam kasus saya), seseorang dapat menggunakan NRvariabel:awk '{print $0, NR}'
andrybak
2
@ Optimus Saya sudah mencoba metode Anda, tetapi mendapatkan ruang ekstra untuk mereka, ada ide tentang cara menghapusnya?
Adil Saju
@AdilSaju sed 's/ //g'ini berfungsi untuk kebutuhan saya, tetapi itu akan menghapus ruang di setiap baris, itulah opsi guntuk dan di mana-mana dalam satu baris.
Eklavyaa
@AdilSaju tolong tambahkan detailnya. Lebih baik ajukan pertanyaan baru.
Optimus Prime
@AdilSaju awk Hapus , suka {print $0"string to append after each line"}.
Culip
8

Jika Anda memilikinya, utilitas lam (laminasi) dapat melakukannya, misalnya:

$ lam filename -s "string after each line"
martin clayton
sumber
4
  1. Shell POSIX murni dan sponge:

    suffix=foobar
    while read l ; do printf '%s\n' "$l" "${suffix}" ; done < file | 
    sponge file
  2. xargsdan printf:

    suffix=foobar
    xargs -L 1 printf "%s${suffix}\n" < file | sponge file
  3. Menggunakan join:

    suffix=foobar
    join file file -e "${suffix}" -o 1.1,2.99999 | sponge file
  4. Alat shell menggunakan paste, yes, head & wc:

    suffix=foobar
    paste file <(yes "${suffix}" | head -$(wc -l < file) ) | sponge file

    Perhatikan bahwa pastemenyisipkan karakter Tab sebelumnya $suffix.

Tentu saja spongedapat diganti dengan file temp, kemudian di mvatas nama file asli, seperti beberapa jawaban lain ...

agc
sumber
1
Tidak ada yang lebih disukai sed, kecuali sumber daya sangat terbatas.
agc
Saya suka solusi non-sed. sedtidak diperlukan untuk pekerjaan sederhana seperti itu.
Bruce
1

Saya lebih suka echo. menggunakan pesta murni:

cat file | while read line; do echo ${line}$string; done
欢乐 的 Xiaox
sumber
-9

Sed agak jelek, Anda bisa melakukannya dengan elegan seperti ini:

hendry@i7 tmp$ cat foo 
bar
candy
car
hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
barbar
candybar
carbar
hendry
sumber
2
Gagal untuk file dengan lebih banyak baris dari batas argumen maksimum shell. Coba: cat foo | saat membaca a; lakukan echo $ {a} bar; dilakukan atau sesuatu seperti itu; itu pengganti yang cocok untuk dalam banyak kasus.
alex
1
Itu juga gagal untuk baris dengan spasi di dalamnya.
Dijeda sampai pemberitahuan lebih lanjut.
1
Er, tidak itu tidak mengecewakan Dennis. batas argumen maksimum shell? Crikey Anda sedang pendantic.
hendry
Ya benar: $ cat foo foo bar baz alex @ armitage: ~ $ untuk saya cat foo; lakukan echo $ {i} bar; dilakukan foobar barbar bazbar tetapi setelah beberapa tes, saya mungkin salah tentang alasan saya, tetapi Dennis benar
alex
3
@ Hendry Ya, ini gagal untuk baris dengan spasi di dalamnya, seperti echo "foo bar" | (for i in `cat`; do echo ${i}bar; done)yang mencetak 2 baris meskipun inputnya 1 baris foo bar(dan catmembaca dari stdin alih-alih file tidak membuat perbedaan untuk ini).
hyde