Saya mencoba untuk memindahkan kolom ke 7 dari file csv saya ke ujung dengan menggunakan
awk -F '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}',OFS= "$file"
di mana $ file adalah file .csv dalam direktori. Namun, hasilnya adalah
awk: ^ syntax error
Adakah yang tahu cara memperbaiki kesalahan ini?
text-processing
awk
rmb
sumber
sumber
^
menunjukkan bagian spesifik dari perintah di mana kesalahan itu terjadi.Jawaban:
The
-F
pilihan membutuhkan sebuah argumen:-F,
misalnya.Akhir
awk
skrip harus dipisahkan dengan(spasi) dengan parameter lainnya.
Jika pemisah bidang adalah
,
dan Anda ingin menyimpannya, dan jika jumlah kolom konstan dan lebih rendah dari atau sama dengan 11, coba ini:sumber
command file > newfile && mv newfile file
. Yang mengatakan, versi terbaru dari GNUawk
untuk mendukung ini:gawk -i inplace '{blah blah}' file
.mv newfile file
Anda dapat menggunakancat newfile > file ; rm -f newfile
- ini mempertahankan inode dan izin darifile
.mktemp
alih-alih nama file sementara hard-coding ke dalam skrip. misalnyatf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
Solusi yang lebih pendek adalah
Saya tidak yakin apakah
,+
akan berfungsi di semuaawk
versi, tetapi berfungsi setidaknya di GNU awk, juga dengan-c
mode ompatibilitas.Penjelasan:
$(NF+1)=$7
: pertama kita tambahkan bidang ke-7 ke akhir baris (bisa$12=$7
dalam hal ini)$7=""
: pada langkah berikutnya bidang ke-7 dihapus (tetapi pembatas di sekitarnya tetap)$0=$0
) memperlakukan beberapa koma sebagai pemisah lapangan (ini dilakukan melalui-F',+'
, di sini+
berarti satu atau lebih kali), dan juga mengatur ulang catatan saat ini$1=$1
untuk memaksa membangun kembali garis menggunakan kekuatan yang ditetapkan sebelumnya bidang output pemisah (diatur oleh opsi-v OFS=,
)1
Input contoh:
keluaran
sumber
,+
seharusnya berfungsi.all,ball,call,,,fall
→all,ball,call,fall
). (2)$(NF+1)=$7
adalah pendekatan yang cerdas. IMHO,$0 = $0 OFS $7
sedikit lebih jelas, hanya beberapa karakter lebih lama, dan sepertinya melakukan hal yang sama. Bisakah Anda memikirkan situasi di mana$0 = $0 OFS $7
tidak melakukan hal yang sama dengan kode Anda?$0=$0 OFS $7
mungkin identik dengan$(NF+1)=$7
, tetapi hanya dengan sisa kode tidak berubah, tidak secara umum.Jika Anda mencetak dengan
OFS=
, jadi tanpa pemisah di antara bidang, Anda cukup menyimpan nilai$7
dalam suatu variabel, mengatur$7
untuk mengosongkan dan mencetak garis dan variabel secara langsung. Anda tidak perlu menentukan semua bidang:sumber
Anda mungkin berarti:
sumber
awk
tidak pernah melihat tanda kutip tunggalOFS=''
, kan? Anda juga bisa mengetikOFS=
; persis sama.Anda tidak secara khusus mengatakan Anda ingin menggunakan awk, dan Anda tidak mengatakan Anda ingin menggunakan editing di-tempat seperti yang disediakan oleh
sed -i
, jadi di sini adalahsed -i
varian. Biasanyaawk
lebih baik untuk bekerja dengan kolom, tetapi ini adalah satu kasus di mana saya lebih sukased
, karena secara alami menangani jumlah kolom yang berubah-ubah.Penjelasan:
-r
memilih regexps yang diperluas sehingga kami menghindari banyak garis miring terbalikTentu saja ini tidak akan berfungsi dengan file yang menyembunyikan tanda koma dalam tanda kutip (atau lebih buruk, luput dari mereka), tetapi awk tidak akan menanganinya tanpa akrobat yang serius. Jika Anda memiliki masalah itu, Anda akan lebih baik dengan
perl
modulText:CSV
ataupython
modulcsv
.sumber
Beberapa
awk
varian (dengan asumsi file Anda ada di dalam variabel$file
)Di sini Anda dapat menggilir semua kolom, mencetak dengan pemisah bidang (OFS), dan mencetak record terminator (ORS) di akhir baris.
Di sini dengan menggunakan regex dan
gensub()
fungsinyamembunuh bidang ke- 7 dan mencetaknya di akhir baris.
$0
adalah seluruh catatan$n
adalah catatan ke- nNF
adalah Jumlah Bidang dari baris saat iniOFS
pemisah yang diajukan keluaranORS
terminator catatan keluaran1
adalah trik untuk mengatakan awktrue
dan mencetak default ($0
).Perbarui ...
Aku hampir lupa, itu mungkin untuk menggeser semua kolom berikut 7 th satu.
sumber
OFS $7
akan lebih kuat dari"," $7
. (2) Saya percaya itu", " $7
salah, sejauh pertanyaan menunjukkan bahwa OP tidak ingin spasi setelah koma. (Dan, jika data input memiliki spasi setelah koma, maka$7
sudah akan dimulai dengan spasi, dan Anda akan menambahkan satu spasi.)OFS $7
, tidak hanya lebih kuat, tetapi bahkan lebih umum ( "tergesa-gesa membuat sampah" )