Sekmeyle ayrılmış dosyaya değer sütunu ekleme


17

Nasıl belirli sayıda satır içeren bir dosyaya değer sütunu ekleyebilirim. Ben böyle bir girdi dosyası var:

Giriş dosyası:

SPATA17 1   217947738
LYPLAL1 1   219383905
FAM47E  4   77192838
SHROOM3 4   77660162
SHROOM3 4   77660731
SHROOM3 4   77662248

Çıktı dosyası:

SPATA17 1   217947738 file1
LYPLAL1 1   219383905 file1
FAM47E  4   77192838  file1
SHROOM3 4   77660162  file1
SHROOM3 4   77660731  file1
SHROOM3 4   77662248  file1

Bu durumda, dosyadaki satır sayısına kadar bir değer sütunu eklemek istiyorum. Değer "dosya1" gibi tutarlı kalır.

Bunun nedeni, bu dosyalardan 100 tanesine sahip olmam. Her dosyayı açmak ve bir sütun yapıştırmak istemiyorum. Ayrıca, bir dizine girip bir değer sütunu ekleyerek bunu otomatikleştirmenin herhangi bir yolu vardır. Değer, son / ilk sütundaki dosyanın her satırına eklenmesi gereken dosya adından gelir.

Yanıtlar:


22

Bunun gibi tek katmanlı bir döngü kullanabilirsiniz:

for f in file1 file2 file3; do sed -i "s/$/\t$f/" $f; done

Listedeki her dosya için bu sed, her satırın sonuna bir sekme ve dosya adı eklemek için kullanılır .

Açıklama:

  • Yerinde değiştirme yapmak için -ibayrağını kullanma sed, dosyanın üzerine yazma
  • İle bir ikame gerçekleştirin s/PATTERN/REPLACEMENT/. Bu örnekte, PATTERN $satırın sonu ve REPLACEMENT \t(= bir SEKME) ve $fdöngü değişkeninden dosya adıdır. s///Kabuk değişkenleri genişletmek, böylece komut çift tırnak içinde.

Kod çalışıyor.İçeriği tırnak içinde açıklayabilir misiniz?
Ron

Sütunlarla çalışırken "awk" kullanıldığı gibi, benzer durumlar için de "sed" kullanılır. "Awk" ve "sed" için acemi oldum.
Ron

@Ron sed, desen değiştirme ve yerinde kaydetme için en pratik olanıdır . Dosyayı kaydetme gereksiniminiz için nispeten uygun bir seçimdi. İşlem yaptığınız aynı dosyaya tekrar yazmanız gerekmiyorsa, awkçalışmak genellikle daha kolaydır.
janos

Şahsen, awkgiriş / çıkış alan ayırıcıları tarafından çok sık devreye giriyorum ve bu yüzden mümkün olduğunca kullanmaktan kaçınmaya çalışarak seddaha çekici hale getiriyorum .
user5359531

11

pasteKomuta varken neden bu güçlü araçları önerdiğinize gelin !

$ cat a
A
B
C
D
$ cat b
1
2
3
4
$ paste a b
A   1
B   2
C   3
D   4

Küçük bir hile pasteile OP'nin amacı için kullanabilirsiniz . Ancak, dosyaları yerinde değiştirmez:

for f in file1 file2 file3; do 
    paste $f <(yes $f | head -n $(cat $f | wc -l)) > $f.new
done

Bu, ilgili dosya adını her dosyanın son sütunu olarak yeni dosyaya yapıştıracaktır filename.new


Teşekkürler! pastekesinlikle gizli bir mücevher olduğunu.
neu242

10

Şunları kullanabilirsiniz awk:

awk '{print $0, FILENAME}' file1 file2 file3 ...

Her dosya farklı bir isme sahip olduğundan, bunu 100 kez yapmak zorundayım.
Ron

Hayır, FILENAMEbir değişkendir awk, işlenen geçerli dosya adına genişler awk. Sadece bir tane yapın, tüm dosyaları besleyin awk.
cuonglm

tamam, ama çıktı her dosyanın yeni bir dosyaya nasıl yönlendirilir? awk işleme sırasında her dosyayı depolar mı?
Ron

Varsa GNU awk 4.1.0veya daha yenisi varsa, -iyerinde düzenlemek için kullanabilirsiniz . Aksi takdirde, awkçıkışını bir geçici dosyaya yönlendirmeli , ardından grepher dosyadan satır çıkarmak için kullanın .
cuonglm

Peki yapabilirsinfor file in *; do awk 'BEGIN{OFS="\t"}{print $0, FILENAME}' $file; done
fedorqui
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.