Menambahkan Kolom nilai dalam file yang dibatasi tab


17

Bagaimana saya bisa menambahkan Kolom nilai dalam file yang memiliki jumlah baris tertentu. Saya memiliki file input seperti ini:

File input:

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

Berkas keluaran:

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

Dalam hal ini, saya ingin menambahkan Kolom nilai, hingga jumlah baris dalam file. Nilai tetap konsisten, seperti "file1".

Alasannya adalah saya memiliki 100 file-file itu. Saya tidak ingin membuka setiap file dan menempelkan sebuah kolom. Juga apakah ada cara untuk mengotomatisasi ini, dengan masuk ke direktori dan menambahkan kolom nilai. Nilai berasal dari nama file, yang harus ditambahkan di setiap baris file di kolom terakhir / pertama.

Jawaban:


22

Anda dapat menggunakan loop satu-liner seperti ini:

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

Untuk setiap file dalam daftar, ini akan digunakan seduntuk menambahkan tab dan nama file pada akhir setiap baris.

Penjelasan:

  • Menggunakan -ibendera dengan seduntuk melakukan penggantian di tempat, menimpa file
  • Lakukan penggantian dengan s/PATTERN/REPLACEMENT/. Dalam contoh ini POLA adalah $, akhir baris, dan PENGGANTIAN adalah \t(= a TAB), dan $fmerupakan nama file, dari variabel loop. The s///perintah dalam tanda kutip ganda sehingga shell dapat memperluas variabel.

Kode berfungsi. Bisakah Anda menjelaskan konten dalam tanda kutip?
Ron

Sama seperti "awk" digunakan saat bekerja dengan kolom, adalah 'sed' juga digunakan untuk situasi yang sama. Saya pemula untuk 'awk' dan 'sed'.
Ron

@Ron sedpaling praktis untuk penggantian pola dan penghematan di tempat. Untuk keperluan Anda menyimpan file, itu adalah opsi yang relatif nyaman. Jika Anda tidak perlu menulis kembali ke file yang sama dengan yang Anda proses, maka awkbiasanya lebih mudah untuk dikerjakan.
janos

Secara pribadi, saya sering tersandung oleh awkpemisah bidang input / output, jadi cobalah untuk menghindari menggunakannya kapan pun memungkinkan, menjadikan sedlebih menarik.
user5359531

11

Ayo mengapa kalian merekomendasikan alat-alat yang ampuh ketika ada pasteperintah!

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

Dengan sedikit tipu daya, Anda bisa menggunakan pasteuntuk tujuan OP. Namun, itu tidak akan menggantikan file di tempat:

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

Ini akan menempelkan nama file masing-masing sebagai kolom terakhir dari setiap file ke file baru filename.new


Terima kasih! pastejelas merupakan permata tersembunyi.
neu242

10

Anda bisa menggunakan awk:

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

Karena setiap file memiliki nama yang berbeda, jadi saya harus melakukan ini 100 kali. Apakah ada cara untuk melakukannya sekali?
Ron

Tidak, FILENAMEadalah variabel dalam awk, itu diperluas ke nama file saat ini yang awksedang diproses. Anda cukup melakukannya satu, beri makan semua file awk.
cuonglm

ok, tetapi bagaimana mengarahkan output ke file baru, dari setiap file? apakah awk menyimpan setiap file saat memproses?
Ron

Jika sudah GNU awk 4.1.0atau lambat, Anda bisa menggunakannya -iuntuk mengedit inplace. Jika tidak, Anda harus mengarahkan ulang awkouput ke file temp, kemudian gunakan grepuntuk mengekstrak baris dari setiap file.
cuonglm

Anda bisa melakukannyafor file in *; do awk 'BEGIN{OFS="\t"}{print $0, FILENAME}' $file; done
fedorqui
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.