Awk - menampilkan baris kedua dari sejumlah file .dat ke satu file

9

Saya memiliki beberapa file seperti: (pada kenyataannya saya memiliki 80)

file1.dat

2 5

6 9

7 1

file2.dat

3 7

8 4

1 3

Saya ingin mengakhiri dengan file yang berisi semua baris kedua. yaitu

output.dat

6 9

8 4

Apa yang saya miliki sejauh loop meskipun nama file tetapi kemudian menulis file di atasnya. misalnya output dari file-file di atas hanya akan

8 4

skrip shell saya terlihat seperti ini:

post.sh

TEND = 80

TINDX = 0

while [ $TINDX - lt $TEND]; do

awk '{ print NR==2 "input-$TINDX.dat > output.dat

TINDX = $((TINDX+1))

done
Rowland
sumber

Jawaban:

17

Hapus whileloop dan manfaatkan ekspansi brace shell dan juga FNR, awkvariabel bawaan:

awk 'FNR==2{print $0 > "output.dat"}' file{1..80}.dat
jimmij
sumber
9
bahkan lebih pendekawk 'FNR==2' file{1..80}.dat > output.dat
Archemar
7

Bagaimana dengan ... head -n 2 input.dat | tail -n 1 | awk...

HarveyP
sumber
Ya, head/ tailpasti sebuah pilihan, Anda tidak perlu awkkemudian.
jimmij
7

sed akan cukup:

sed -sn 2p file{1..80}.dat > output.dat

-s opsi diperlukan untuk mencetak baris ke-2 dari setiap file, jika tidak hanya baris ke-2 dari file pertama yang akan dicetak.

aragaer
sumber
2

sedsolusi aragaer adalah yang terbaik, ya. Tapi saya karena saya menikmati sedikit head|tailpemotongan, punya head|tailsolusi yang mendukung banyak file, bukan hanya satu input.dat. Menggunakan for-loop, alih-alih meneruskan daftar file ke sed, juga membuatnya lebih mudah untuk melakukan hal lain dengan file sebelum / sesudah mengekstraksi baris kedua dengan sed.

# empty output.dat first
rm output.dat

# have a one-liner
for file in *.dat; do head -2 $file | tail -1 >> output.dat; done 

Versi multi-baris yang banyak dikomentari:

NB: kode di bawah ini akan berjalan. Kita bebas untuk menempatkan linebreak setelah |, &&atau ||, dan melanjutkan perintah kami pada baris berikutnya; kami bahkan dapat memberikan komentar di antaranya. Saya menghabiskan waktu bertahun - tahun untuk tidak mengetahui hal ini (dan tidak benar-benar melihatnya di mana pun). Gaya ini kurang berguna pada prompt interaktif, tetapi membersihkan file skrip tanpa akhir.

# empty output.dat first
rm output.dat

for file in *.dat; do
    # file -> lines 1 and 2 of file
    head -2 $file |
    # lines 1 and 2 of file -> line 2 of file >> appended to output.dat
    tail -1 >> output.dat
done
Esteis
sumber
0

Jelas ada banyak cara untuk melakukan ini - saya pikir saya suka @ sed aragaer jawaban terbaik .

Inilah salah satu yang menggunakan murni bash builtins dan tidak perlu membayar utilitas eksternal apa pun:

for f in file{1..80}.dat; do
    { read && read && printf "%s\n" "$REPLY"; } < "$f"
done > output.dat
Trauma Digital
sumber
0

Untuk efisiensi penggunaan awkdan sedjawaban di sini pada banyak file, lebih baik menggunakan nextfilepernyataan untuk melewati pemrosesan baris yang tidak diinginkan awk.

awk 'FNR==2{ print >"output.dat"; nextfile}' infile{1..80}.dat

dan dengan sed, kita dapat keluar saat memproses atas 3 rd line dan sedakan memproses file selanjutnya.

sed -sn '2p;3q' infile{1..80}.dat > output.dat
αғsнιη
sumber