Saya memiliki file dalam format berikut
Kolom1 Kolom2 str1 1 str2 2 str3 3
Saya ingin kolom disusun ulang. Saya mencoba perintah di bawah ini
potong -f2, 1 file.txt
Perintah tidak menyusun ulang kolom. Adakah yang tahu mengapa ini tidak berhasil?
Terima kasih.
cut
sekali tidak mendukung perintah pemesanan ulang intuitif ini. Pokoknya, tip lain: Anda dapat menggunakanawk
's-FS
dan-OFS
pilihan untuk masukan menggunakan adat dan pemisah lapangan keluaran (seperti-d
dan--output-delimiter
untukcut
).FS
adalah pilihan,OFS
adalah variabel. egawk -v OFS=";" -F"\t" '{print $2,$1}'
| sed 's/\r//' |
awk
awk '{print $4 "\t" $2 "\t" $6 "\t" $7}' file
Anda juga dapat menggabungkan
cut
danpaste
:via komentar: Dimungkinkan untuk menghindari bashisme dan menghapus satu contoh pemotongan dengan melakukan:
sumber
cut
berfungsi dengan baik untuk kolom panjang variabel selama Anda memiliki pemisah kolom yang unik.bash
isme dan menghapus satu contohcut
dengan melakukan:paste file.txt file.txt | cut -f2,3
hanya menggunakan shell,
sumber
"$col2"
dan"$col1"
- mungkin ada metacharacters shell atau shenanigans lainnya dalam data.Anda dapat menggunakan Perl untuk itu:
Keuntungan menjalankan perl adalah bahwa (jika Anda tahu Perl) Anda dapat melakukan lebih banyak perhitungan pada F daripada mengatur ulang kolom.
sumber
perl -ae print
bekerja seperticat
untuk sayaMenggunakan
join
:Catatan:
-t $'\t'
Dalam GNUjoin
yang lebih intuitif-t '\t'
tanpa yang$
gagal, ( coreutils v8.28 dan sebelumnya?); itu mungkin bug yang$
harus diperbaiki. Lihat: unix gabung pemisah char .join
membutuhkan dua nama file, meskipun hanya ada satu file yang sedang dikerjakan. Menggunakan nama yang sama dua kali trikjoin
untuk melakukan tindakan yang diinginkan.Untuk sistem dengan sumber daya rendah
join
menawarkan jejak yang lebih kecil daripada beberapa alat yang digunakan dalam jawaban lain:sumber
Baru saja mengerjakan sesuatu yang sangat mirip, saya bukan ahli tapi saya pikir saya akan membagikan perintah yang telah saya gunakan. Saya memiliki multi-kolom csv yang saya hanya membutuhkan 4 kolom dan kemudian saya perlu memesan ulang.
File saya adalah pipa '|' dibatasi tetapi itu bisa ditukar.
Memang benar-benar kasar dan siap tetapi dapat disesuaikan dengan!
sumber
Menggunakan sed
Gunakan sed dengan sub-ekspresi bersarang ekspresi reguler dasar untuk menangkap dan menyusun ulang konten kolom. Pendekatan ini paling cocok ketika ada sejumlah pemotongan untuk menyusun ulang kolom, seperti dalam kasus ini.
Ide dasarnya adalah mengelilingi bagian-bagian yang menarik dari pola pencarian dengan
\(
dan\)
, yang dapat diputar kembali dalam pola penggantian dengan\#
mana#
mewakili posisi sekuensial dari subekspresi dalam pola pencarian.Sebagai contoh:
hasil:
Teks di luar subekspresi dipindai tetapi tidak disimpan untuk diputar dalam string pengganti.
Meskipun pertanyaannya tidak membahas kolom lebar tetap, kami akan membahas di sini karena ini adalah ukuran yang layak untuk setiap solusi yang diajukan. Untuk kesederhanaan, mari kita asumsikan file dibatasi oleh ruang meskipun solusinya dapat diperluas untuk pembatas lainnya.
Ruang Runtuh
Untuk mengilustrasikan penggunaan paling sederhana, mari kita asumsikan bahwa banyak spasi dapat diciutkan menjadi spasi tunggal, dan nilai kolom kedua diakhiri dengan EOL (dan bukan spasi empuk).
Mengajukan:
Mengubah:
Mempertahankan Lebar Kolom
Sekarang mari kita memperluas metode ke file dengan kolom lebar konstan, sementara memungkinkan kolom menjadi lebar berbeda.
Mengajukan:
Mengubah:
Terakhir meskipun contoh pertanyaan tidak memiliki string dengan panjang yang tidak sama, ungkapan sed ini mendukung kasus ini.
Mengajukan:
Mengubah:
Bandingkan dengan metode penataan ulang kolom lainnya di bawah shell
Anehnya untuk alat manipulasi file, awk tidak cocok untuk memotong dari bidang ke akhir rekaman. Dalam sed ini dapat dilakukan dengan menggunakan ekspresi reguler, misalnya di
\(xxx.*$\)
manaxxx
ekspresi untuk mencocokkan kolom.Menggunakan rekatkan dan potong subkulit menjadi sulit saat menerapkan skrip shell di dalam. Kode yang berfungsi dari commandline gagal diurai ketika dibawa ke dalam skrip shell. Setidaknya ini adalah pengalaman saya (yang mendorong saya ke pendekatan ini).
sumber
Memperluas jawaban dari @Met, juga menggunakan Perl:
Jika input dan output dibatasi TAB:
Jika input dan output dibatasi spasi:
Di sini,
-e
beri tahu Perl untuk mencari kode sebaris, daripada dalam file skrip terpisah,-n
membaca baris input 1 sekaligus,-l
menghapus pemisah rekaman input (\n
pada * NIX) setelah membaca baris (mirip denganchomp
), dan menambahkan output merekam pemisah (\n
pada * NIX) untuk masing-masingprint
,-a
membagi jalur input pada spasi putih ke dalam array@F
,-F'\t'
dalam kombinasi dengan-a
membagi jalur input pada TAB, bukannya spasi putih ke dalam array@F
.@F[1, 0]
adalah array yang terdiri dari elemen ke-2 dan ke-1@F
, dalam urutan ini. Ingat bahwa array di Perl diindekskan nol, sedangkan bidang dalamcut
1-diindeks. Jadi bidang dalam@F[0, 1]
adalah bidang yang sama dengan yang ada dicut -f1,2
.Perhatikan bahwa notasi tersebut memungkinkan manipulasi input yang lebih fleksibel daripada pada beberapa jawaban lain yang diposting di atas (yang baik untuk tugas sederhana). Sebagai contoh:
sumber