Bash'de, bir dosyadaki her satırdan sonra nasıl bir dize eklerim?


112

Bash kullanarak bir dosyadaki her satırdan sonra nasıl bir dize eklerim? Sed komutu kullanılarak yapılabilir, eğer öyleyse nasıl?

Yanıtlar:


188

Parametre sedaracılığıyla yerinde düzenlemeye izin verirseniz -i:

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

Değilse, geçici bir dosya oluşturmanız gerekir:

typeset TMP_FILE=$( mktemp )

touch "${TMP_FILE}"
cp -p filename "${TMP_FILE}"
sed -e 's/$/string after each line/' "${TMP_FILE}" > filename

Neden touchgeçici dosya yapıyorsun ? Ve sedemri, başarısına koşullu yapardım cpveya orijinal kaybedilebilirdi.
sonraki duyuruya kadar duraklatıldı.

Geçici adı hızlıca ayırmak için dosyaya dokundum. Bu gerekli olmayabilir. Sed komutunu cp'nin başarısına bağlı kılma konusunda haklı olduğunuzu düşünüyorum. Bu düzeltmeyi yapmak için neden kodu düzenlemiyorsunuz? Biraz umursamıyorum! Sevgiler, Tom
Tom DeGisi

Bir satırdan önce bir dize eklemeye ne dersiniz ?
Oxwivi

10
@Oxwivi: sed -e 's/^/string after each line/' -i filename $ satır sonu anlamına gelir. ^ satırın başlangıcı anlamına gelir.
Tom DeGisi

Ben sed içine boru ediyorsam, sed 's/^/string after each line/'ben (her satıra prepends) beklediğiniz ama ne yapar sed 's/^/string after each line/'değil (benim ekleme dizeyle bütün çizgi yerine geçer) gelmez. Ne oluyor? @TomDeGisi herhangi bir fikir?
philadams

17

Kullanmayı tercih ederim awk. Yalnızca bir sütun varsa kullanın $0, yoksa son sütunla değiştirin.

Tek yön,

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

veya bu,

awk '$0=$0"string to append after each line"' file > new_file

1
Ayrıca, satır numaralarını eklemek için (benim durumumda olduğu gibi) NRdeğişken kullanılabilir:awk '{print $0, NR}'
andrybak

2
@optimus Metodunuzu denedim, ancak onlar arasında fazladan bir boşluk var, bunları nasıl kaldıracağınıza dair bir fikriniz var mı?
Adil Saju

@AdilSaju sed 's/ //g'bu benim ihtiyacım için çalıştı, ancak her satırdaki boşluğu kaldıracak, bu g, bir satırdaki her yerde ve her yerde seçenek .
Eklavyaa

@AdilSaju lütfen detay ekleyin. Yeni bir soru sormak daha iyi.
Optimus Prime

@AdilSaju awk Kaldır , gibi {print $0"string to append after each line"}.
Culip

8

Elinizde varsa, lam (laminat) yardımcı programı bunu yapabilir, örneğin:

$ lam filename -s "string after each line"

4
  1. Saf POSIX kabuğu ve sponge:

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

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

    suffix=foobar
    join file file -e "${suffix}" -o 1.1,2.99999 | sponge file
  4. Kabuk araçları kullanılarak paste, yes, head ve wc:

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

    Not pasteBir ekler Tab önce kömürü $suffix.

Elbette spongegeçici bir dosya ile değiştirilebilir, daha sonra mvdiğer bazı cevaplarda olduğu gibi orijinal dosya adı üzerine ...


1
sedKaynaklar çok sınırlı olmadıkça bunların hiçbiri tercih edilmez.
agc

Sed olmayan çözümü beğendim. sedbu kadar basit bir iş için gerekli değildir.
Bruce

1

Tercih ederim echo. saf bash kullanarak:

cat file | while read line; do echo ${line}$string; done

-9

Sed biraz çirkin, böyle zarifçe yapabilirsin:

hendry@i7 tmp$ cat foo 
bar
candy
car
hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
barbar
candybar
carbar

2
Kabuğun maksimum bağımsız değişken sınırından daha fazla satıra sahip dosyalar için başarısız olur. Deneyin: cat foo | a okurken; do echo $ {a} çubuğu; bunun yerine yapıldı veya bunun gibi bir şey; çoğu durumda bunun yerine geçer.
alex

1
Ayrıca, içlerinde boşluk olan satırlar için de başarısız olur.
sonraki duyuruya kadar duraklatıldı.

1
Hayır, Dennis başarısız olmaz. kabuğun maksimum argüman sınırı? Crikey, sarkık oluyorsun.
hendry

Evet yapar: $ cat foo foo bar baz alax @ armitage: ~ $ for i in cat foo; do echo $ {i} çubuğu; foobar barbar bazbar yaptım ama bazı testlerden sonra mantığım konusunda yanılıyor olabilirim, ama Dennis haklı
alex

3
@hendry Evet, echo "foo bar" | (for i in `cat`; do echo ${i}bar; done)giriş 1 satır olmasına rağmen 2 satır yazdıran satırlar gibi boşluklar olan satırlar için bu başarısız olur foo bar(ve catdosya yerine stdin'den okumak bunun için bir fark yaratmaz ).
hyde
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.