Kolom Tunggal ke Beberapa Kolom Baris dan Kolom yang Dapat Disesuaikan AWK

Saya memiliki data masukan yang terlihat seperti ini dalam format "mm/yyyy, data":

Location 1
08/2012, 44.1
09/2012, 34.2
10/2012, 24.3
11/2012, 14.4
12/2012, 04.5
01/2013, 14.6
02/2013, 24.7
Location 2
08/2012, 33.1
09/2012, 44.2
10/2012, 55.3
11/2012, 66.4
12/2012, 77.5
01/2013, 88.6
02/2013, 11.7
Location 3
08/2012, 35.1
09/2012, 45.2
10/2012, 55.3
11/2012, 66.4
12/2012, 77.5
01/2013, 71.6 
02/2013, 19.7
Location 4
etc
etc

dan saya menggunakan skrip awk yaitu ini -

awk '}printf (NR %276 == 0 )? $0"\n" : $0"\t" }' file input (Saya menggunakan NR%276 karena itu adalah panjang kolom untuk setiap kolom berulang baru atau "Lokasi" pada data asli yang ditunjukkan pada bagian di atas). Awk dapatkah membagi potongan data satu kolom dari "Lokasi X" ke "Lokasi Y" dalam n kolom keluaran?

Saya mendapatkan keluaran tetapi tidak benar menjalankan keluaran dari file masukan kolom tunggal secara horizontal dengan gaya bungkus teks atau "mengular" seperti ini - Lokasi 1 mm/tttt, data1 data2 dll Lokasi 2 mm/tttt, data1 data2 dll Lokasi 3 mm/tttt, data1 data2 dst.

Sebagai gantinya, saya memerlukan data keluaran saya menyerupai ini tetapi untuk 276 baris dan sekitar 150 kolom/lokasi atau ke potongan kolom terakhir dari data "Lokasi" dari 276 baris dalam file masukan (contoh singkat ditunjukkan di atas). Akan sangat membantu jika menambah jumlah baris menjadi 277 misalnya untuk 03/2013 atau menjadi >150 lokasi.

Location 1        Location 2        Location 3
08/2012, 44.1     08/2012, 33.1     08/2012, 35.1
09/2012, 34.2     09/2012, 44.2     09/2012, 45.2
10/2012, 24.3     10/2012, 55.3     10/2012, 55.3
11/2012, 14.4     11/2012, 66.4     11/2012, 66.4
12/2012, 04.5     12/2012, 77.5     12/2012, 77.5
01/2013, 14.6     01/2013, 88.6     01/2013, 71.6
02/2013, 24.7     02/2013, 11.7     02/2013, 19.7

Terima kasih!!


awk
person user2100039    schedule 18.03.2013    source sumber


Jawaban (3)


Awk lain yang bisa Anda coba:

awk '!/^[0-9]/{n=0} {n++; A[n]=A[n] (A[n]?OFS:x) $0} END{for(i=1; i<=n; i++) print A[i]}' OFS='\t' file

Untuk mencetak kolom kedua saja di setiap lokasi:

awk '!/^[0-9]/{n=0} {n++; A[n]=A[n] (A[n]?OFS:x) $2} END{for(i=1; i<=n; i++) print A[i]}' OFS='\t' file
person Scrutinizer    schedule 18.03.2013
comment
oke, itu berhasil. saya harus memikirkan cara mencetak hanya $2 atau kolom kedua untuk setiap lokasi atau tajuk kolom. ada ide? saat ini, ia sedang mencetak $1 dan $2. terima kasih, - person user2100039; 19.03.2013
comment
@ user2100039: Menambahkan perbaikan cepat - person Scrutinizer; 19.03.2013

coba satu kalimat ini:

 awk '/^Location/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file

catatan

  • baris di atas mengubah masukan satu kolom Anda menjadi keluaran 3 kolom, tidak menangani 276 rows barang Anda. (Saya rasa kita tidak perlu melakukan perhitungan itu.)
  • dalam keluaran, kolomnya tab dipisahkan.
  • baris dan kolom tidak dikodekan secara keras, Anda dapat mengujinya dengan data asli Anda

uji dengan data Anda:

kent$  awk '/^Location/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file      
Location 1      Location 2      Location 3
08/2012, 44.1   08/2012, 33.1   08/2012, 35.1
09/2012, 34.2   09/2012, 44.2   09/2012, 45.2
10/2012, 24.3   10/2012, 55.3   10/2012, 55.3
11/2012, 14.4   11/2012, 66.4   11/2012, 66.4
12/2012, 04.5   12/2012, 77.5   12/2012, 77.5
01/2013, 14.6   01/2013, 88.6   01/2013, 71.6 
02/2013, 24.7   02/2013, 11.7   02/2013, 19.7

EDIT untuk komentar

 awk '!/^[0-9]/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=277&&m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file 
  • baris di atas tidak akan cocok dengan 'Lokasi' yang diberi kode keras, tetapi untuk judul non-angka (juga berfungsi untuk "lokasi")
  • 276, 277 Saya tidak tahu apa maksudnya. tetapi satu baris di atas akan untuk setiap blok (lokasi dalam contoh Anda), mencetak maksimal 276 baris. jika nomor baris kurang dari 276, cetak saja jumlah baris sebenarnya.

Anda dapat mengubah sedikit one-liner, agar sesuai dengan kebutuhan Anda.

Semoga beruntung.

person Kent    schedule 18.03.2013
comment
Maaf, col header Lokasi 1, dll untuk contoh ini tetapi kenyataannya itu adalah nama yang berubah sehingga Lokasi tidak pernah muncul di file input. Bisakah ia mencari string dengan panjang berapa pun? - person user2100039; 18.03.2013
comment
di file input, baris data = 276 dan termasuk header baris = 277. terima kasih lagi- - person user2100039; 18.03.2013
comment
@ user2100039 jadi apa lokasi di data Anda yang sebenarnya? mengikuti beberapa pola? lagi pula, menurutku kalimatku bisa membantumu memulai. - person Kent; 18.03.2013
comment
nama seperti Eagle, Westridge, MesaTop, dll. yang unik untuk setiap potongan header + 276 baris data. terima kasih, - person user2100039; 18.03.2013
comment
ada masalah setelah [0-9]/{j=0; - regexp yang tidak dihentikan pada { sebelum j. Ide ide? - person user2100039; 18.03.2013

Dengan asumsi setiap lokasi memiliki jumlah baris data yang sama:

numcols=$(tac input_file | awk '$1 == "Location" {print $2; exit}')
pr -t -s --columns=$numcols input_file

Karena Anda mengetahui berapa banyak baris di setiap lokasi, hitung jumlah lokasi dengan:

numcols=$(( $(wc -l < input_file) / 277 ))
person glenn jackman    schedule 18.03.2013
comment
terima kasih - Header Lokasi di file sebenarnya tidak menggunakan kata Lokasi melainkan lokasi unik seperti Flatiron, Wolfbog, Mesavista, dll. Baris data = 276 + header untuk setiap potongan data yang perlu dicetak sebagai kolom baru. terima kasih! - person user2100039; 18.03.2013
comment
Glenn- Saya mendapatkan kesalahan nama variabel ilegal saat menjalankan kode ini dan pesan kesalahan yang sama saat menjalankan kode numcols secara terpisah untuk menemukan jumlah lokasi. Ide ide? - person user2100039; 19.03.2013
comment
Benar-benar? shell apa yang Anda gunakan (bash/csh/...)? Tunjukkan kepada kami kode yang sebenarnya Anda jalankan. Perhatikan bahwa tanda kurung luar digandakan dan tanda kurung dalam adalah tunggal - person glenn jackman; 19.03.2013