@MaxMackie askubuntu.com/questions/88142/… . Saya tidak bisa mendapatkan mod di sana pada jam ini, jadi saya menandainya meminta mereka untuk bermigrasi jika mereka mau; sudah ada jawaban yang diterima jadi saya tidak yakin apakah mereka mau
Michael Mrozek
@MichaelMrozek, hmmm apa yang biasanya terjadi dalam situasi ini? Apakah kita hanya menyimpan duplikatnya?
Selain cara memotong dan menata ulang ladang (tercakup dalam jawaban lain), ada masalah bidang CSV yang unik.
Jika data Anda termasuk dalam kategori "aneh" ini, sedikit pemfilteran sebelum dan sesudah pemilahan dapat mengatasinya. Filter yang ditunjukkan di bawah memerlukan karakter \x01, \x02, \x03, \x04untuk tidak muncul di mana saja di data Anda.
Berikut adalah filter yang melilit tempat awkpembuangan sederhana .
Catatan: bidang-lima memiliki tata letak "bidang kutip" yang tidak valid / tidak lengkap, tetapi tidak berbahaya di akhir baris (tergantung pada pengurai CSV). Tapi, tentu saja, hal itu akan menyebabkan hasil unexpedted bermasalah jika itu untuk ditukarkan jauh dari saat ini akhir-of-baris posisi.
Memperbarui; user121196 telah menunjukkan bug ketika koma mendahului kutipan trailing. Inilah solusinya.
Data
cat <<'EOF'>file
field one,"fie,ld,two",field"three","field,\",four","field,five
"15111 N. Hayden Rd., Ste 160,",""
EOF
field one
"fie,ld,two"
field"three""field,\",four""field,five
"15111 N. Hayden Rd., Ste 160,"""
Berikut adalah filter pra , diperluas dengan komentar.
The pasca Filter hanya pembalikan \x01. \x02, \x03,\x04
sed -r '
s/^/,/# add a leading comma delimiter
s/\\"/\x01/g # obfuscate escaped quotation-mark (\")
s/,"([^"]*)"/,\x02\1\x03/g # obfuscate quotation-marks
s/,"/,\x02/# when no trailing quote on last field :MC # obfuscate commas embedded in quotes
s/\x02([^\x03]*),([^\x03]*)/\x02\1\x04\2/g
tMC
s/^,// # remove spurious leading delimiter'
bagaimana Anda menghapus kolom ke-n berdasarkan filter ini?
user121196
@ user121196 - Seperti disebutkan dalam kalimat pembuka, jawaban ini menunjukkan cara untuk membuat data CSV lebih konsisten .. mis. dengan secara sementara mengganti koma yang disematkan kutipan dengan karakter token netral ... dan kemudian mengembalikannya menjadi koma setelah pindah / potong / hapus. Sekali lagi, seperti yang disebutkan, langkah move / cut / delete digantikan oleh field-dump awk sederhana .
Peter.O
1
gagal untuk kasus ini: "15111 N. Hayden Rd., Ste 160,", ""
user121196
@ user121196: Terima kasih telah menunjukkannya. Saya telah memperbarui jawabannya dengan perbaikan.
Peter.O
15
Ini tergantung pada apakah file CSV Anda menggunakan koma hanya untuk pembatas, atau jika Anda memiliki kegilaan seperti:
bidang satu, "bidang, dua", bidang tiga
Ini mengasumsikan Anda menggunakan file CSV sederhana:
Menghapus kolom
Anda dapat menyingkirkan satu kolom banyak cara; Saya menggunakan kolom 2 sebagai contoh. Cara termudah adalah menggunakan cut, yang memungkinkan Anda menentukan pembatas -ddan bidang mana yang ingin Anda cetak -f; ini memerintahkannya untuk membagi koma dan bidang keluaran 1, dan bidang 3 sampai akhir:
$ cut -d,-f1,3-/path/to/your/file
Jika Anda benar-benar perlu menggunakan sed, Anda dapat menulis ekspresi reguler yang cocok dengan n-1bidang pertama , bidang nth, dan sisanya, dan lewati menghasilkan nth (di sini nadalah 2, sehingga kelompok pertama adalah 1waktu yang cocok:) \{1\}:
$ sed 's/\(\([^,]\+,\)\{1\}\)[^,]\+,\(.*\)/\1\3/'/path/to/your/file
Ada beberapa cara untuk melakukan ini awk, tidak ada yang sangat elegan. Anda dapat menggunakan forlingkaran, tetapi berurusan dengan koma yang tertinggal adalah hal yang menyakitkan; mengabaikan bahwa itu akan menjadi seperti:
Pada seddasarnya ini adalah ekspresi yang sama seperti sebelumnya, tetapi Anda juga menangkap kolom target dan memasukkan grup itu beberapa kali dalam penggantian:
$ sed 's/\(\([^,]\+,\)\{1\}\)\([^,]\+,\)\(.*\)/\1\3\3\4/'/path/to/your/file
Dalam awkcara for loop itu akan menjadi sesuatu seperti (lagi-lagi mengabaikan tanda koma):
Karena ini CSV, Anda juga perlu BEGIN { FS=","; OFS=","; }.
1
Saya pikir bahkan FS = OFS = "," akan bekerja.
5
Diberi file terbatas-ruang dalam format berikut:
12345
Anda dapat menghapus bidang 2 dengan awk seperti:
awk '{ sub($2,""); print}' file
yang kembali
1345
Ganti kolom 2 dengan kolom n jika perlu.
Untuk menduplikasi kolom 2,
awk '{ col = $2 " " $2; $2 = col; print }' file
yang kembali
122345
Untuk mengganti kolom 2 dan 3,
awk '{temp = $2; $2 = $3; $3 = temp; print}'
yang kembali
13245
awk umumnya sangat bagus dalam berurusan dengan konsep bidang . Jika Anda berurusan dengan CSV, dan bukan file yang dibatasi ruang, Anda dapat menggunakannya
awk -F,
untuk menentukan bidang Anda sebagai koma, bukan spasi (yang merupakan default). Ada sejumlah sumber daya awk online yang bagus, salah satunya saya cantumkan sebagai sumber di bawah ini.
Saya tidak tahu banyak tentang awk, tetapi tampaknya menghasilkan ruang-dipisahkan bahkan jika pemisah lapangan (pemisah ,lapangan hanya mengontrol bagaimana ia menangani input)
Michael Mrozek
@MichaelMrozek: ya, itu adalah variabel aws OFS yang mengontrol pemisah bidang keluaran.
enzotib
Ya, dan seperti yang saya sebutkan dalam jawaban saya, Anda dapat melewatkan opsi -F untuk awk untuk mengubah pembatas (misalnya -F,)
Jawaban:
Selain cara memotong dan menata ulang ladang (tercakup dalam jawaban lain), ada masalah bidang CSV yang unik.
Jika data Anda termasuk dalam kategori "aneh" ini, sedikit pemfilteran sebelum dan sesudah pemilahan dapat mengatasinya. Filter yang ditunjukkan di bawah memerlukan karakter
\x01
,\x02
,\x03
,\x04
untuk tidak muncul di mana saja di data Anda.Berikut adalah filter yang melilit tempat
awk
pembuangan sederhana .Catatan: bidang-lima memiliki tata letak "bidang kutip" yang tidak valid / tidak lengkap, tetapi tidak berbahaya di akhir baris (tergantung pada pengurai CSV). Tapi, tentu saja, hal itu akan menyebabkan hasil unexpedted bermasalah jika itu untuk ditukarkan jauh dari saat ini akhir-of-baris posisi.
Memperbarui; user121196 telah menunjukkan bug ketika koma mendahului kutipan trailing. Inilah solusinya.
Data
Kode
Hasil:
Berikut adalah filter pra , diperluas dengan komentar.
The pasca Filter hanya pembalikan
\x01
.\x02
,\x03
,\x04
sumber
Ini tergantung pada apakah file CSV Anda menggunakan koma hanya untuk pembatas, atau jika Anda memiliki kegilaan seperti:
Ini mengasumsikan Anda menggunakan file CSV sederhana:
Menghapus kolom
Anda dapat menyingkirkan satu kolom banyak cara; Saya menggunakan kolom 2 sebagai contoh. Cara termudah adalah menggunakan
cut
, yang memungkinkan Anda menentukan pembatas-d
dan bidang mana yang ingin Anda cetak-f
; ini memerintahkannya untuk membagi koma dan bidang keluaran 1, dan bidang 3 sampai akhir:Jika Anda benar-benar perlu menggunakan
sed
, Anda dapat menulis ekspresi reguler yang cocok dengann-1
bidang pertama , bidangn
th, dan sisanya, dan lewati menghasilkann
th (di sinin
adalah 2, sehingga kelompok pertama adalah1
waktu yang cocok:)\{1\}
:Ada beberapa cara untuk melakukan ini
awk
, tidak ada yang sangat elegan. Anda dapat menggunakanfor
lingkaran, tetapi berurusan dengan koma yang tertinggal adalah hal yang menyakitkan; mengabaikan bahwa itu akan menjadi seperti:Saya merasa lebih mudah untuk menampilkan bidang 1 dan kemudian menggunakan
substr
untuk melakukan semuanya setelah bidang 2:Ini menjengkelkan untuk kolom lebih jauh
Duplikat kolom
Pada
sed
dasarnya ini adalah ekspresi yang sama seperti sebelumnya, tetapi Anda juga menangkap kolom target dan memasukkan grup itu beberapa kali dalam penggantian:Dalam
awk
cara for loop itu akan menjadi sesuatu seperti (lagi-lagi mengabaikan tanda koma):The
substr
cara:(tcdyl datang dengan metode yang lebih baik dalam jawabannya )
Memindahkan kolom
Saya pikir
sed
solusinya mengikuti secara alami dari yang lain, tetapi mulai menjadi sangat panjangsumber
awk
adalah taruhan terbaik Anda.awk
mencetak bidang dengan nomor, jadi ...Untuk menghapus kolom, jangan cetak:
Untuk mengubah urutan:
Arahkan ulang ke file output.
awk
dapat memformat output juga.Output format awk
sumber
BEGIN { FS=","; OFS=","; }
.Diberi file terbatas-ruang dalam format berikut:
Anda dapat menghapus bidang 2 dengan awk seperti:
yang kembali
Ganti kolom 2 dengan kolom n jika perlu.
Untuk menduplikasi kolom 2,
yang kembali
Untuk mengganti kolom 2 dan 3,
yang kembali
awk umumnya sangat bagus dalam berurusan dengan konsep bidang . Jika Anda berurusan dengan CSV, dan bukan file yang dibatasi ruang, Anda dapat menggunakannya
untuk menentukan bidang Anda sebagai koma, bukan spasi (yang merupakan default). Ada sejumlah sumber daya awk online yang bagus, salah satunya saya cantumkan sebagai sumber di bawah ini.
Sumber untuk # 3
sumber
awk
, tetapi tampaknya menghasilkan ruang-dipisahkan bahkan jika pemisah lapangan (pemisah,
lapangan hanya mengontrol bagaimana ia menangani input)Ini akan berfungsi untuk menghapus
Memasukkan
Keluaran
sumber