Perintah cut adalah alat kanonik untuk menghapus "kolom" dari file teks. Dalam konteks ini, "kolom" dapat didefinisikan sebagai rentang karakter atau byte yang diidentifikasi berdasarkan posisi fisiknya pada baris, atau rentang bidang yang dibatasi oleh pemisah.
Saya telah menulis tentang menggunakan perintah AWK sebelumnya. Dalam panduan terperinci ini, saya akan menjelaskan empat contoh penting dan praktis dari perintah cut di Linux yang akan sangat membantu Anda.
4 Contoh praktis perintah Cut di Linux
Jika mau, Anda dapat menonton video ini yang menjelaskan contoh praktis perintah cut yang sama dengan yang saya cantumkan di artikel.
1. Bekerja dengan rentang karakter
Saat dipanggil dengan -c
opsi baris perintah, perintah potong akan menghapus karakter rentang.
Seperti filter lainnya, perintah cut tidak mengubah file input di tempatnya tetapi akan menyalin data yang dimodifikasi ke output standarnya. Anda bertanggung jawab untuk mengarahkan output perintah ke file untuk menyimpan hasilnya atau menggunakan pipa untuk mengirimkannya sebagai input ke perintah lain.
Jika Anda telah mengunduh file uji sampel yang digunakan dalam video di atas, Anda dapat melihat BALANCE.txt
file data, langsung dari perangkat lunak akuntansi yang digunakan istri saya di tempat kerjanya:
sh$ head BALANCE.txt
ACCDOC ACCDOCDATE ACCOUNTNUM ACCOUNTLIB ACCDOCLIB DEBIT CREDIT
4 1012017 623477 TIDE SCHEDULE ALNEENRE-4701-LOC 00000001615,00
4 1012017 445452 VAT BS/ENC ALNEENRE-4701-LOC 00000000323,00
4 1012017 4356 PAYABLES ALNEENRE-4701-LOC 00000001938,00
5 1012017 623372 ACCOMODATION GUIDE ALNEENRE-4771-LOC 00000001333,00
5 1012017 445452 VAT BS/ENC ALNEENRE-4771-LOC 00000000266,60
5 1012017 4356 PAYABLES ALNEENRE-4771-LOC 00000001599,60
6 1012017 4356 PAYABLES FACT FA00006253 - BIT QUIROBEN 00000001837,20
6 1012017 445452 VAT BS/ENC FACT FA00006253 - BIT QUIROBEN 00000000306,20
6 1012017 623795 TOURIST GUIDE BOOK FACT FA00006253 - BIT QUIROBEN 00000001531,00
Ini adalah file teks dengan lebar tetap karena bidang data diisi dengan jumlah spasi yang bervariasi untuk memastikannya ditampilkan sebagai tabel yang disejajarkan dengan baik.
Sebagai akibat wajar, kolom data selalu dimulai dan diakhiri pada posisi karakter yang sama pada setiap baris. Ada sedikit jebakan:terlepas dari namanya, cut
perintah sebenarnya mengharuskan Anda untuk menentukan rentang data yang ingin Anda simpan , bukan rentang yang ingin Anda hapus . Jadi, jika saya membutuhkan hanya ACCOUNTNUM
dan ACCOUNTLIB
kolom dalam file data di atas, saya akan menulis bahwa:
sh$ cut -c 25-59 BALANCE.txt | head
ACCOUNTNUM ACCOUNTLIB
623477 TIDE SCHEDULE
445452 VAT BS/ENC
4356 /accountPAYABLES
623372 ACCOMODATION GUIDE
445452 VAT BS/ENC
4356 PAYABLES
4356 PAYABLES
445452 VAT BS/ENC
623795 TOURIST GUIDE BOOK
Apa itu rentang?
Seperti yang baru saja kita lihat, perintah cut mengharuskan kita menentukan rentang data yang ingin kita simpan. Jadi, mari kita perkenalkan secara lebih formal apa itu range:untuk cut
perintah, rentang ditentukan oleh posisi awal dan akhir yang dipisahkan oleh tanda hubung. Rentang berbasis 1, yaitu item pertama dari baris adalah item nomor 1, bukan 0. Rentang sudah termasuk:awal dan akhir akan dipertahankan dalam output, serta semua karakter di antaranya. Ini adalah kesalahan untuk menentukan rentang yang posisi akhirnya sebelum ("lebih rendah") dari posisi awalnya. Sebagai jalan pintas, Anda dapat menghilangkan awal atau nilai akhir seperti yang dijelaskan pada tabel di bawah ini:
a-b
:rentang antara a dan b (inklusif)a
:setara dengan rentanga-a
-b
:setara dengan1-a
b-
:setara denganb-∞
Perintah cut memungkinkan Anda untuk menentukan beberapa rentang dengan memisahkannya dengan koma. Berikut adalah beberapa contohnya:
# Keep characters from 1 to 24 (inclusive)
cut -c -24 BALANCE.txt
# Keep characters from 1 to 24 and 36 to 59 (inclusive)
cut -c -24,36-59 BALANCE.txt
# Keep characters from 1 to 24, 36 to 59 and 93 to the end of the line (inclusive)
cut -c -24,36-59,93- BALANCE.txt
Satu batasan (atau fitur, tergantung pada cara Anda melihatnya) dari cut
perintahnya adalah tidak akan pernah menyusun ulang data . Jadi, perintah berikut akan menghasilkan hasil yang sama persis dengan yang sebelumnya, meskipun rentang ditentukan dalam urutan yang berbeda:
cut -c 93-,-24,36-59 BALANCE.txt
Anda dapat memeriksanya dengan mudah menggunakan diff
perintah:
diff -s <(cut -c -24,36-59,93- BALANCE.txt) \
<(cut -c 93-,-24,36-59 BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical
Demikian pula, cut
perintah jangan pernah menduplikasi data :
# One might expect that could be a way to repeat
# the first column three times, but no...
cut -c -10,-10,-10 BALANCE.txt | head -5
ACCDOC
4
4
4
5
Perlu disebutkan ada proposal untuk -o
opsi untuk mengangkat dua batasan terakhir tersebut, memungkinkan cut
utilitas untuk menyusun ulang atau menggandakan data. Namun hal ini ditolak oleh komite POSIX“karena jenis peningkatan ini berada di luar cakupan standar draf IEEE P1003.2b.”
Untuk saya sendiri, saya tidak tahu ada versi pemotongan yang mengimplementasikan proposal itu sebagai perpanjangan. Tetapi jika Anda melakukannya, silakan bagikan dengan kami menggunakan bagian komentar!
2. Bekerja dengan rentang byte
Saat dipanggil dengan -b
opsi baris perintah, perintah cut akan menghapus byte rentang.
Pada pandangan pertama, tidak ada perbedaan yang jelas antara karakter dan byte rentang:
sh$ diff -s <(cut -b -24,36-59,93- BALANCE.txt) \
<(cut -c -24,36-59,93- BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical
Itu karena file data sampel saya menggunakan pengkodean karakter US-ASCII (“charset”) sebagai file -i
perintah dapat menebaknya dengan benar:
sh$ file -i BALANCE.txt
BALANCE.txt: text/plain; charset=us-ascii
Dalam pengkodean karakter itu, ada pemetaan satu-ke-satu antara karakter dan byte. Dengan hanya menggunakan satu byte, Anda secara teoritis dapat menyandikan hingga 256 karakter yang berbeda (angka, huruf, tanda baca, simbol, ... ) Dalam praktiknya, angka tersebut jauh lebih rendah karena pengkodean karakter membuat ketentuan untuk beberapa nilai khusus (seperti 32 atau 65 karakter kontrol umumnya ditemukan). Bagaimanapun, bahkan jika kita dapat menggunakan rentang byte penuh, itu akan jauh dari cukup untuk menyimpan berbagai tulisan manusia. Jadi, hari ini, pemetaan satu-ke-satu antara karakter dan byte lebih merupakan pengecualian daripada norma dan hampir selalu digantikan oleh pengkodean multibyte UTF-8 di mana-mana. Sekarang mari kita lihat bagaimana perintah cut dapat menanganinya.
Bekerja dengan karakter multibyte
Seperti yang saya katakan sebelumnya, contoh file data yang digunakan sebagai contoh untuk artikel tersebut berasal dari software akuntansi yang digunakan oleh istri saya. Itu menambahkan dia memperbarui perangkat lunak itu baru-baru ini dan, setelah itu, file teks yang diekspor sedikit berbeda. Saya membiarkan Anda mencoba melihat perbedaannya sendiri:
sh$ head BALANCE-V2.txt
ACCDOC ACCDOCDATE ACCOUNTNUM ACCOUNTLIB ACCDOCLIB DEBIT CREDIT
4 1012017 623477 TIDE SCHEDULE ALNÉENRE-4701-LOC 00000001615,00
4 1012017 445452 VAT BS/ENC ALNÉENRE-4701-LOC 00000000323,00
4 1012017 4356 PAYABLES ALNÉENRE-4701-LOC 00000001938,00
5 1012017 623372 ACCOMODATION GUIDE ALNÉENRE-4771-LOC 00000001333,00
5 1012017 445452 VAT BS/ENC ALNÉENRE-4771-LOC 00000000266,60
5 1012017 4356 PAYABLES ALNÉENRE-4771-LOC 00000001599,60
6 1012017 4356 PAYABLES FACT FA00006253 - BIT QUIROBEN 00000001837,20
6 1012017 445452 VAT BS/ENC FACT FA00006253 - BIT QUIROBEN 00000000306,20
6 1012017 623795 TOURIST GUIDE BOOK FACT FA00006253 - BIT QUIROBEN 00000001531,00
Judul bagian ini mungkin membantu Anda menemukan apa yang telah berubah. Tapi, ketahuan atau tidak, mari kita lihat sekarang konsekuensi dari perubahan itu:
sh$ cut -c 93-,-24,36-59 BALANCE-V2.txt
ACCDOC ACCDOCDATE ACCOUNTLIB DEBIT CREDIT
4 1012017 TIDE SCHEDULE 00000001615,00
4 1012017 VAT BS/ENC 00000000323,00
4 1012017 PAYABLES 00000001938,00
5 1012017 ACCOMODATION GUIDE 00000001333,00
5 1012017 VAT BS/ENC 00000000266,60
5 1012017 PAYABLES 00000001599,60
6 1012017 PAYABLES 00000001837,20
6 1012017 VAT BS/ENC 00000000306,20
6 1012017 TOURIST GUIDE BOOK 00000001531,00
19 1012017 SEMINAR FEES 00000000080,00
19 1012017 PAYABLES 00000000080,00
28 1012017 MAINTENANCE 00000000746,58
28 1012017 VAT BS/ENC 00000000149,32
28 1012017 PAYABLES 00000000895,90
31 1012017 PAYABLES 00000000240,00
31 1012017 VAT BS/DEBIT 00000000040,00
31 1012017 ADVERTISEMENTS 00000000200,00
32 1012017 WATER 00000000202,20
32 1012017 VAT BS/DEBIT 00000000020,22
32 1012017 WATER 00000000170,24
32 1012017 VAT BS/DEBIT 00000000009,37
32 1012017 PAYABLES 00000000402,03
34 1012017 RENTAL COSTS 00000000018,00
34 1012017 PAYABLES 00000000018,00
35 1012017 MISCELLANEOUS CHARGES 00000000015,00
35 1012017 VAT BS/DEBIT 00000000003,00
35 1012017 PAYABLES 00000000018,00
36 1012017 LANDLINE TELEPHONE 00000000069,14
36 1012017 VAT BS/ENC 00000000013,83
Saya telah menyalin di atas output perintah in-extenso jadi pasti ada yang salah dengan perataan kolom.
Penjelasannya adalah file data asli hanya berisi karakter US-ASCII (simbol, tanda baca, angka dan huruf latin tanpa tanda diakritik)
Tetapi jika Anda melihat lebih dekat pada file yang dihasilkan setelah pembaruan perangkat lunak, Anda dapat melihat bahwa file data ekspor baru sekarang mempertahankan huruf beraksen. Misalnya, perusahaan bernama “ALNÉENRE” sekarang dieja dengan benar padahal sebelumnya diekspor sebagai “ALNEENRE” (tanpa aksen)
file -i
utilitas tidak melewatkan perubahan itu karena sekarang melaporkan file sebagai dikodekan UTF-8:
sh$ file -i BALANCE-V2.txt
BALANCE-V2.txt: text/plain; charset=utf-8
Untuk melihat bagaimana huruf beraksen dikodekan dalam file UTF-8, kita dapat menggunakan hexdump
utilitas yang memungkinkan kita untuk melihat secara langsung byte dalam file:
# To reduce clutter, let's focus only on the second line of the file
sh$ sed '2!d' BALANCE-V2.txt
4 1012017 623477 TIDE SCHEDULE ALNÉENRE-4701-LOC 00000001615,00
sh$ sed '2!d' BALANCE-V2.txt | hexdump -C
00000000 34 20 20 20 20 20 20 20 20 20 31 30 31 32 30 31 |4 101201|
00000010 37 20 20 20 20 20 20 20 36 32 33 34 37 37 20 20 |7 623477 |
00000020 20 20 20 54 49 44 45 20 53 43 48 45 44 55 4c 45 | TIDE SCHEDULE|
00000030 20 20 20 20 20 20 20 20 20 20 20 41 4c 4e c3 89 | ALN..|
00000040 45 4e 52 45 2d 34 37 30 31 2d 4c 4f 43 20 20 20 |ENRE-4701-LOC |
00000050 20 20 20 20 20 20 20 20 20 20 20 20 20 30 30 30 | 000|
00000060 30 30 30 30 31 36 31 35 2c 30 30 20 20 20 20 20 |00001615,00 |
00000070 20 20 20 20 20 20 20 20 20 20 20 0a | .|
0000007c
Pada baris 00000030 dari hexdump
output, setelah banyak spasi (byte 20
), Anda dapat melihat:
- huruf
A
dikodekan sebagai byte41
, - huruf
L
dikodekan dalam byte4c
, - dan huruf
N
dikodekan sebagai byte4e
.
Tapi, huruf besar LATIN CAPITAL LETTER E WITH ACUTE (karena itu adalah nama resmi dari huruf É dalam standar Unicode) dikodekan menggunakan dua byte c3 89
Dan inilah masalahnya:menggunakan cut
perintah dengan rentang yang dinyatakan sebagai posisi byte berfungsi dengan baik untuk pengkodean panjang tetap, tetapi tidak untuk panjang variabel seperti UTF-8 atau Shift JIS. Ini dijelaskan dengan jelas dalam ekstrak non-normatif standar POSIX berikut:
Versi sebelumnya dari utilitas cut bekerja di lingkungan di mana byte dan karakter dianggap setara (pemrosesan modulodan dalam beberapa implementasi). Di dunia karakter multi-byte yang diperluas, opsi -b baru telah ditambahkan.
Hei, tunggu sebentar! Saya tidak menggunakan -b
opsi dalam contoh "salah" di atas, tetapi -c
pilihan. Jadi, tidak boleh yang berhasil?!?
Ya, itu harus :sangat disayangkan, tetapi kita berada di tahun 2018 dan meskipun demikian, pada GNU Coreutils 8.30, implementasi GNU dari utilitas cut masih tidak menangani karakter multi-byte dengan benar. Mengutip dokumentasi GNU, -c
pilihannya adalah “Sama dengan -b untuk saat ini, tetapi internasionalisasi akan mengubahnya[… ]” — penyebutan yang hadir sejak lebih dari 10 tahun sekarang!
Di sisi lain, implementasi OpenBSD dari utilitas cut sesuai dengan POSIX, dan akan menghormati pengaturan lokal saat ini untuk menangani karakter multi-byte dengan benar:
# Ensure subseauent commands will know we are using UTF-8 encoded
# text files
openbsd-6.3$ export LC_CTYPE=en_US.UTF-8
# With the `-c` option, cut works properly with multi-byte characters
openbsd-6.3$ cut -c -24,36-59,93- BALANCE-V2.txt
ACCDOC ACCDOCDATE ACCOUNTLIB DEBIT CREDIT
4 1012017 TIDE SCHEDULE 00000001615,00
4 1012017 VAT BS/ENC 00000000323,00
4 1012017 PAYABLES 00000001938,00
5 1012017 ACCOMODATION GUIDE 00000001333,00
5 1012017 VAT BS/ENC 00000000266,60
5 1012017 PAYABLES 00000001599,60
6 1012017 PAYABLES 00000001837,20
6 1012017 VAT BS/ENC 00000000306,20
6 1012017 TOURIST GUIDE BOOK 00000001531,00
19 1012017 SEMINAR FEES 00000000080,00
19 1012017 PAYABLES 00000000080,00
28 1012017 MAINTENANCE 00000000746,58
28 1012017 VAT BS/ENC 00000000149,32
28 1012017 PAYABLES 00000000895,90
31 1012017 PAYABLES 00000000240,00
31 1012017 VAT BS/DEBIT 00000000040,00
31 1012017 ADVERTISEMENTS 00000000200,00
32 1012017 WATER 00000000202,20
32 1012017 VAT BS/DEBIT 00000000020,22
32 1012017 WATER 00000000170,24
32 1012017 VAT BS/DEBIT 00000000009,37
32 1012017 PAYABLES 00000000402,03
34 1012017 RENTAL COSTS 00000000018,00
34 1012017 PAYABLES 00000000018,00
35 1012017 MISCELLANEOUS CHARGES 00000000015,00
35 1012017 VAT BS/DEBIT 00000000003,00
35 1012017 PAYABLES 00000000018,00
36 1012017 LANDLINE TELEPHONE 00000000069,14
36 1012017 VAT BS/ENC 00000000013,83
Seperti yang diharapkan, saat menggunakan -b
mode byte alih-alih -c
mode karakter, implementasi pemotongan OpenBSD berperilaku seperti cut
sebelumnya :
openbsd-6.3$ cut -b -24,36-59,93- BALANCE-V2.txt
ACCDOC ACCDOCDATE ACCOUNTLIB DEBIT CREDIT
4 1012017 TIDE SCHEDULE 00000001615,00
4 1012017 VAT BS/ENC 00000000323,00
4 1012017 PAYABLES 00000001938,00
5 1012017 ACCOMODATION GUIDE 00000001333,00
5 1012017 VAT BS/ENC 00000000266,60
5 1012017 PAYABLES 00000001599,60
6 1012017 PAYABLES 00000001837,20
6 1012017 VAT BS/ENC 00000000306,20
6 1012017 TOURIST GUIDE BOOK 00000001531,00
19 1012017 SEMINAR FEES 00000000080,00
19 1012017 PAYABLES 00000000080,00
28 1012017 MAINTENANCE 00000000746,58
28 1012017 VAT BS/ENC 00000000149,32
28 1012017 PAYABLES 00000000895,90
31 1012017 PAYABLES 00000000240,00
31 1012017 VAT BS/DEBIT 00000000040,00
31 1012017 ADVERTISEMENTS 00000000200,00
32 1012017 WATER 00000000202,20
32 1012017 VAT BS/DEBIT 00000000020,22
32 1012017 WATER 00000000170,24
32 1012017 VAT BS/DEBIT 00000000009,37
32 1012017 PAYABLES 00000000402,03
34 1012017 RENTAL COSTS 00000000018,00
34 1012017 PAYABLES 00000000018,00
35 1012017 MISCELLANEOUS CHARGES 00000000015,00
35 1012017 VAT BS/DEBIT 00000000003,00
35 1012017 PAYABLES 00000000018,00
36 1012017 LANDLINE TELEPHONE 00000000069,14
36 1012017 VAT BS/ENC 00000000013,83
3. Bekerja dengan bidang
Dalam beberapa hal, bekerja dengan bidang dalam file teks yang dibatasi lebih mudah untuk cut
utilitas, karena hanya perlu menemukan pembatas bidang (satu byte) pada setiap baris, menyalin kemudian kata demi kata konten bidang ke output tanpa mengganggu masalah penyandian apa pun.
Berikut adalah contoh file teks yang dibatasi:
sh$ head BALANCE.csv
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;ACCDOCLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;ALNEENRE-4701-LOC;00000001615,00;
4;1012017;445452;VAT BS/ENC;ALNEENRE-4701-LOC;00000000323,00;
4;1012017;4356;PAYABLES;ALNEENRE-4701-LOC;;00000001938,00
5;1012017;623372;ACCOMODATION GUIDE;ALNEENRE-4771-LOC;00000001333,00;
5;1012017;445452;VAT BS/ENC;ALNEENRE-4771-LOC;00000000266,60;
5;1012017;4356;PAYABLES;ALNEENRE-4771-LOC;;00000001599,60
6;1012017;4356;PAYABLES;FACT FA00006253 - BIT QUIROBEN;;00000001837,20
6;1012017;445452;VAT BS/ENC;FACT FA00006253 - BIT QUIROBEN;00000000306,20;
6;1012017;623795;TOURIST GUIDE BOOK;FACT FA00006253 - BIT QUIROBEN;00000001531,00;
Anda mungkin mengetahui format file tersebut sebagai CSV (untuk Nilai yang Dipisahkan Koma), meskipun pemisah bidang tidak selalu berupa koma. Misalnya, titik koma (;
) sering dijumpai sebagai pemisah bidang, dan sering kali merupakan pilihan default saat mengekspor data sebagai "CSV" di negara-negara yang sudah menggunakan koma sebagai pemisah desimal (seperti yang kami lakukan di Prancis — oleh karena itu pilihan karakter itu dalam file sampel saya ). Varian populer lainnya menggunakan karakter tab sebagai pemisah bidang, menghasilkan apa yang terkadang disebut file nilai yang dipisahkan tab. Terakhir, di dunia Unix dan Linux, titik dua (:
) adalah pemisah bidang lain yang relatif umum yang mungkin Anda temukan, misalnya, dalam /etc/passwd
standar dan /etc/group
file.
Saat menggunakan format file teks yang dibatasi, Anda memberikan perintah cut rentang bidang untuk tetap menggunakan -f
opsi, dan Anda harus menentukan pembatas menggunakan -d
opsi (tanpa -d
opsi, utilitas potong default ke karakter tab untuk pemisah):
sh$ cut -f 5- -d';' BALANCE.csv | head
ACCDOCLIB;DEBIT;CREDIT
ALNEENRE-4701-LOC;00000001615,00;
ALNEENRE-4701-LOC;00000000323,00;
ALNEENRE-4701-LOC;;00000001938,00
ALNEENRE-4771-LOC;00000001333,00;
ALNEENRE-4771-LOC;00000000266,60;
ALNEENRE-4771-LOC;;00000001599,60
FACT FA00006253 - BIT QUIROBEN;;00000001837,20
FACT FA00006253 - BIT QUIROBEN;00000000306,20;
FACT FA00006253 - BIT QUIROBEN;00000001531,00;
Menangani baris yang tidak berisi pembatas
Tetapi bagaimana jika beberapa baris dalam file input tidak mengandung pembatas? Sangat menggoda untuk membayangkan itu sebagai baris yang hanya berisi bidang pertama. Tapi ini bukan apa yang dilakukan utilitas potong.
Secara default, saat menggunakan -f
opsi, utilitas cut akan selalu menampilkan baris kata demi kata yang tidak mengandung pembatas (mungkin dengan asumsi ini adalah baris non-data seperti header atau semacam komentar):
sh$ (echo "# 2018-03 BALANCE"; cat BALANCE.csv) > BALANCE-WITH-HEADER.csv
sh$ cut -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
# 2018-03 BALANCE
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00
Menggunakan -s
pilihan, Anda dapat membalikkan perilaku itu, jadi cut
akan selalu mengabaikan baris tersebut:
sh$ cut -s -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00
00000001333,00;
Jika Anda sedang dalam mood hackish, Anda dapat memanfaatkan fitur tersebut sebagai cara yang relatif tidak jelas untuk menjaga hanya baris yang berisi karakter tertentu:
# Keep lines containing a `e`
sh$ printf "%s\n" {mighty,bold,great}-{condor,monkey,bear} | cut -s -f 1- -d'e'
Mengubah pembatas output
Sebagai perpanjangan, implementasi GNU cut memungkinkan untuk menggunakan pemisah bidang yang berbeda untuk output menggunakan --output-delimiter
pilihan:
sh$ cut -f 5,6- -d';' --output-delimiter="*" BALANCE.csv | head
ACCDOCLIB*DEBIT*CREDIT
ALNEENRE-4701-LOC*00000001615,00*
ALNEENRE-4701-LOC*00000000323,00*
ALNEENRE-4701-LOC**00000001938,00
ALNEENRE-4771-LOC*00000001333,00*
ALNEENRE-4771-LOC*00000000266,60*
ALNEENRE-4771-LOC**00000001599,60
FACT FA00006253 - BIT QUIROBEN**00000001837,20
FACT FA00006253 - BIT QUIROBEN*00000000306,20*
FACT FA00006253 - BIT QUIROBEN*00000001531,00*
Perhatikan, dalam hal ini, semua kemunculan pemisah bidang diganti, dan tidak hanya kemunculan pada batas rentang yang ditentukan pada argumen baris perintah.
4. Ekstensi GNU non-POSIX
Berbicara tentang ekstensi GNU non-POSIX, beberapa di antaranya bisa sangat berguna. Perlu disebutkan ekstensi berikut berfungsi sama baiknya dengan byte, karakter (untuk apa artinya dalam implementasi GNU saat ini) atau rentang bidang:--complement
Pikirkan opsi itu seperti tanda seru di alamat sed (!
); alih-alih menyimpan data yang cocok dengan rentang yang diberikan, cut
akan menyimpan data TIDAK cocok dengan rentang
# Keep only field 5
sh$ cut -f 5 -d';' BALANCE.csv |head -3
ACCDOCLIB
ALNEENRE-4701-LOC
ALNEENRE-4701-LOC
# Keep all but field 5
sh$ cut --complement -f 5 -d';' BALANCE.csv |head -3
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;00000001615,00;
4;1012017;445452;VAT BS/ENC;00000000323,00;
--zero-terminated
(-z
)
gunakan karakter NUL sebagai terminator baris alih-alih karakter baris baru. -z
opsi ini sangat berguna ketika data Anda mungkin berisi karakter baris baru yang disematkan, seperti saat bekerja dengan nama file (karena baris baru adalah karakter yang valid dalam nama file, tetapi NUL tidak).
Untuk menunjukkan bagaimana -z
opsi berfungsi, mari kita lakukan sedikit eksperimen. Pertama, kita akan membuat file yang namanya berisi baris baru yang disematkan:
bash$ touch
Sekarang mari kita asumsikan saya ingin menampilkan 5 karakter pertama dari setiap *.txt
nama file. Solusi naif akan gagal total di sini:
sh$ ls -1 *.txt | cut -c 1-5
BALAN
BALAN
EMPTY
FILE
WITH
NAME.
Anda mungkin sudah membaca ls
dirancang untuk konsumsi manusia, dan menggunakannya dalam pipa perintah adalah anti-pola (memang). Jadi mari kita gunakan find
perintah sebagai gantinya:
sh$ find . -name '*.txt' -printf "%f\n" | cut -c 1-5
BALAN
EMPTY
FILE
WITH
NAME.
BALAN
dan … yang pada dasarnya menghasilkan hasil kesalahan yang sama seperti sebelumnya (walaupun dalam urutan yang berbeda karena ls
mengurutkan nama file secara implisit, sesuatu yang find
perintah tidak melakukannya).
Masalahnya adalah dalam kedua kasus, cut
perintah tidak dapat membedakan antara karakter baris baru yang menjadi bagian dari bidang data (nama file), dan karakter baris baru yang digunakan sebagai penanda akhir rekaman. Tetapi, menggunakan byte NUL (\0
) saat terminator garis menghilangkan kebingungan sehingga kami akhirnya dapat memperoleh hasil yang diharapkan:
# I was told (?) some old versions of tr require using \000 instead of \0
# to denote the NUL character (let me know if you needed that change!)
sh$ find . -name '*.txt' -printf "%f\0" | cut -z -c 1-5| tr '\0' '\n'
BALAN
EMPTY
BALAN
Dengan contoh terbaru itu, kami menjauh dari inti artikel ini yaitu cut
memerintah. Jadi, saya akan membiarkan Anda mencoba mencari tahu sendiri arti dari "%f\0"
yang funky setelah -printf
argumen find
perintah atau mengapa saya menggunakan tr
perintah di akhir pipeline.
Lebih banyak yang bisa dilakukan dengan perintah Cut
Saya baru saja menunjukkan yang paling umum dan menurut saya penggunaan perintah Cut yang paling penting. Anda dapat menerapkan perintah dengan cara yang lebih praktis. Itu tergantung pada penalaran dan imajinasi logis Anda.
Jangan ragu untuk menggunakan bagian komentar di bawah untuk memposting temuan Anda. Dan, seperti biasa, jika Anda menyukai artikel ini, jangan lupa untuk membagikannya ke situs web dan media sosial favorit Anda!