4 Základné a praktické použitie príkazu Cut v systéme Linux
Príkaz cut v Linuxe umožňuje odstránenie údajov na každom riadku súboru. Prečítajte si tento návod, aby ste vedeli, ako ho efektívne použiť na spracovanie textového alebo dátového súboru CSV.
Príkaz vystrihnúť je kanonický nástroj na odstránenie „stĺpcov“ z textového súboru. V tomto kontexte môže byť „stĺpec“ definovaný ako rozsah znakov alebo bajtov identifikovaných ich fyzickou pozíciou na riadku alebo rozsah polí oddelených oddeľovačom.
O používaní príkazov AWK som písal už skôr. V tejto podrobnej príručke vysvetlím štyri základné a praktické príklady príkazu cut v systéme Linux, ktoré vám pomôžu.
4 Praktické príklady príkazu Vystrihnúť v Linuxe
Ak chcete, môžete si pozrieť toto video vysvetľujúce tie isté praktické príklady príkazu cut, ktoré som uviedol v článku.
1. Práca s rozsahmi znakov
Pri vyvolaní pomocou voľby príkazového riadka -c príkaz cut odstráni rozsahy znakov.
Ako každý iný filter, príkaz cut nezmení vstupný súbor na mieste, ale skopíruje upravené údaje na jeho štandardný výstup. Je vašou zodpovednosťou presmerovať výstup príkazu do súboru, aby sa výsledok uložil, alebo použiť potrubie na jeho odoslanie ako vstup do iného príkazu.
Ak ste si stiahli vzorové testovacie súbory použité vo videu vyššie, môžete si pozrieť dátový súbor BALANCE.txt, ktorý pochádza priamo z účtovného softvéru, ktorý moja manželka používa vo svojej práci:
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,00Toto je textový súbor s pevnou šírkou, pretože dátové polia sú vyplnené premenlivým počtom medzier, aby sa zabezpečilo, že sa zobrazia ako pekne zarovnaná tabuľka.
Dôsledkom toho je, že stĺpec údajov vždy začína a končí na rovnakej pozícii znaku na každom riadku. Je tu však malé úskalie: napriek svojmu názvu príkaz cut v skutočnosti vyžaduje, aby ste špecifikovali rozsah údajov, ktoré chcete uchovať, nie rozsah, ktorý chcete odstrániť. Ak teda potrebujem iba stĺpce ACCOUNTNUM a ACCOUNTLIB v dátovom súbore vyššie, napísal by som toto:
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čo je rozsah?
Ako sme práve videli, príkaz cut vyžaduje, aby sme zadali rozsah údajov, ktoré chceme zachovať. Predstavme si teda formálnejšie, čo je rozsah: pre príkaz cut je rozsah definovaný počiatočnou a koncovou pozíciou oddelenými pomlčkou. Rozsahy sú založené na 1, to znamená, že prvá položka v riadku je číslo položky 1, nie 0. Rozsahy sú vrátane: začiatok a koniec sa zachovajú vo výstupe, rovnako ako všetky znaky medzi nimi. Je chybou určiť rozsah, ktorého koncová pozícia je pred (“nižšia”) ako počiatočná pozícia. Ako skratku môžete vynechať počiatočnú alebo koncovú hodnotu, ako je popísané v tabuľke nižšie:
a-b: rozsah medzi a a b (vrátane)a: ekvivalentné rozsahua-a-b: ekvivalentné s1-ab-: ekvivalentné sb-∞
Príkazy rezu vám umožňujú určiť niekoľko rozsahov oddelením čiarkou. Tu je pár príkladov:
# 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
Jedným obmedzením (alebo funkciou, v závislosti od toho, ako to vidíte) príkazu cut je, že nikdy nezmení poradie údajov. Nasledujúci príkaz teda vytvorí presne rovnaký výsledok ako predchádzajúci, napriek tomu, že rozsahy sú špecifikované v inom poradí:
cut -c 93-,-24,36-59 BALANCE.txtMôžete to jednoducho skontrolovať pomocou príkazu diff:
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 identicalPodobne príkaz cut nikdy neduplikuje údaje:
# 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
5Za zmienku stojí návrh na možnosť -o na odstránenie týchto dvoch posledných obmedzení, čo umožňuje nástroju cut zmeniť poradie alebo duplikovať údaje. Výbor POSIX to však zamietol„pretože tento typ vylepšenia je mimo rámca návrhu štandardu IEEE P1003.2b. ”
Pokiaľ ide o mňa, nepoznám žiadnu skrátenú verziu implementujúcu tento návrh ako rozšírenie. Ale ak áno, podeľte sa o to s nami pomocou sekcie komentárov!
2. Práca s bajtovými rozsahmi
Pri vyvolaní pomocou voľby príkazového riadka -b príkaz cut odstráni rozsahy bajtov.
Na prvý pohľad nie je zjavný rozdiel medzi rozsahmi znakov a bajtov:
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 identicalJe to preto, že môj vzorový dátový súbor používa kódovanie znakov US-ASCII („charset“), pretože príkaz file -i to dokáže správne uhádnuť:
sh$ file -i BALANCE.txt
BALANCE.txt: text/plain; charset=us-asciiV tomto kódovaní znakov existuje mapovanie jedna ku jednej medzi znakmi a bajtmi. Použitím iba jedného bajtu môžete teoreticky zakódovať až 256 rôznych znakov (číslice, písmená, interpunkčné znamienka, symboly, ...) V praxi je tento počet oveľa nižší, pretože kódovanie znakov umožňuje určité špeciálne hodnoty (napríklad 32 alebo 65 riadiacich znakov všeobecne nájdené). Každopádne, aj keby sme mohli použiť celý rozsah bajtov, zďaleka by to nestačilo na uloženie rozmanitosti ľudského písania. Takže dnes je mapovanie jedna ku jednej medzi znakmi a bajtom skôr výnimkou ako normou a je takmer vždy nahradené všadeprítomným viacbajtovým kódovaním UTF-8. Pozrime sa teraz, ako to zvládne príkaz cut.
Práca s viacbajtovými znakmi
Ako som už povedal, vzorové dátové súbory použité ako príklady pre tento článok pochádzajú z účtovného softvéru, ktorý používa moja manželka. Pridáva, že nedávno aktualizovala tento softvér a potom boli exportované textové súbory jemne odlišné. Nechám vás, aby ste sa pokúsili zistiť rozdiel sami:
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
Názov tejto časti vám môže pomôcť zistiť, čo sa zmenilo. Ale či už sme našli alebo nenašli, pozrime sa teraz na dôsledky tejto zmeny:
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,83Skopíroval som nad výstup príkazu in-extenso, takže by malo byť zrejmé, že sa niečo pokazilo so zarovnaním stĺpcov.
Vysvetlením je, že pôvodný dátový súbor obsahoval iba znaky US-ASCII (symbol, interpunkciu, čísla a latinské písmená bez akýchkoľvek diakritických znamienok)
Ak sa však dôkladne pozriete na súbor vytvorený po aktualizácii softvéru, môžete vidieť, že nový súbor s údajmi exportu teraz zachováva písmená s diakritikou. Napríklad spoločnosť s názvom „ALNÉENRE“ je teraz správne napísaná, zatiaľ čo predtým bola exportovaná ako „ALNEENRE“ (bez prízvuku)
Obslužnému programu file -i táto zmena neunikla, pretože teraz hlási súbor ako súbor s kódovaním UTF-8:
sh$ file -i BALANCE-V2.txt
BALANCE-V2.txt: text/plain; charset=utf-8Ak chcete vidieť, ako sú kódované písmená s diakritikou v súbore UTF-8, môžeme použiť nástroj hexdump, ktorý nám umožňuje pozrieť sa priamo na bajty v súbore:
# 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 | .|
0000007cNa riadku 00000030 výstupu hexdump po hromade medzier (bajt 20) môžete vidieť:
písmeno
Aje zakódované ako bajt41,písmeno
Lje zakódované a bajt4c,a písmeno
Nje zakódované ako bajt4e.
Ale veľké LATINSKÉ VEĽKÉ PÍSMENO E S AKÚTNYM (ako je to oficiálny názov písmena É v štandarde Unicode) je zakódované pomocou dva bajty c3 89
A tu je problém: použitie príkazu cut s rozsahmi vyjadrenými ako bajtové pozície funguje dobre pre kódovania s pevnou dĺžkou, ale nie pre kódovania s premenlivou dĺžkou, ako je UTF-8 alebo Shift JIS. Toto je jasne vysvetlené v nasledujúcom nenormačnom extrakte štandardu POSIX:
Skoršie verzie nástroja cut fungovali v prostredí, kde sa bajty a znaky považovali za ekvivalentné (modulo
a <tab> spracovanie v niektorých implementáciách). V rozšírenom svete viacbajtových znakov bola pridaná nová voľba -b.
Hej, počkaj chvíľu! Vo vyššie uvedenom príklade „chyby“ som nepoužil možnosť -b, ale možnosť -c. Takže, nemalo by to fungovať?!?
Áno, malo by: je to nešťastné, ale sme v roku 2018 a napriek tomu, od GNU Coreutils 8.30, GNU implementácia cut utility stále nezvláda multi -bajtové znaky správne. Aby sme citovali dokumentáciu GNU, možnosť -c je „Zatiaľ to isté ako -b, ale internacionalizácia to zmení[… ] ” — zmienka, ktorá existuje už viac ako 10 rokov!
Na druhej strane, OpenBSD implementácia nástroja cut je kompatibilná s POSIX a bude rešpektovať aktuálne miestne nastavenia, aby správne spracovala viacbajtové znaky:
# 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,83Ako sa očakávalo, pri použití bajtového režimu -b namiesto znakového režimu -c sa implementácia OpenBSD cut správa ako starý cut:
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,833. Práca s poľami
V určitom zmysle je práca s poľami v textovom súbore s oddeľovačmi pre pomôcku cut jednoduchšia, pretože bude musieť nájsť iba (jednobajtové) oddeľovače polí v každom riadku a potom doslovne skopírovať obsah poľa. na výstup bez toho, aby ste sa obťažovali akýmikoľvek problémami s kódovaním.
Tu je vzorový textový súbor s oddeľovačmi:
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;Tento formát súboru možno poznáte ako CSV (pre hodnotu oddelenú čiarkou), aj keď oddeľovač poľa nie je vždy čiarkou. Napríklad, bodkočiarka (;) sa často používa ako oddeľovač polí a často je to predvolená voľba pri exporte údajov ako „CSV “ v krajinách, ktoré už používajú čiarku ako oddeľovač desatinných miest ( ako to robíme vo Francúzsku – teda výber tohto znaku v mojom vzorovom súbore). Ďalší populárny variant používa ako oddeľovač polí znak tabulátora a vytvára to, čo sa niekedy nazýva súbor hodnôt oddelených tabulátormi. Napokon, vo svete Unixu a Linuxu je dvojbodka (:) ďalším relatívne bežným oddeľovačom polí, ktorý môžete nájsť napríklad v štandardnom /etc/passwd a /etc/group súbory.
Pri použití formátu textového súboru s oddeľovačmi poskytnete príkazu cut rozsah polí, ktoré sa majú zachovať, pomocou voľby -f a musíte zadať oddeľovač pomocou -d možnosť (bez možnosti -d, nástroj na vystrihnutie predvolene použije znak tabulátora pre oddeľovač):
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;Manipulačné čiary neobsahujúce oddeľovač
Ale čo ak niektorý riadok vo vstupnom súbore neobsahuje oddeľovač? Je lákavé si to predstaviť ako riadok obsahujúci iba prvé pole. Ale toto nie robí nástroj cut.
V predvolenom nastavení, pri použití voľby -f, obslužný program cut vždy doslovne vypíše riadok, ktorý neobsahuje oddeľovač (pravdepodobne za predpokladu, že ide o riadok bez údajov, ako je hlavička alebo komentár nejakého druhu ):
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,00Pomocou možnosti -s môžete toto správanie zvrátiť, takže príkaz cut bude takýto riadok vždy ignorovať:
sh$ cut -s -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00
00000001333,00;Ak máte hackerskú náladu, môžete túto funkciu využiť ako relatívne nejasný spôsob, ako ponechať iba riadky obsahujúce daný znak:
# Keep lines containing a `e`
sh$ printf "%s\n" {mighty,bold,great}-{condor,monkey,bear} | cut -s -f 1- -d'e'Zmena oddeľovača výstupu
Ako rozšírenie GNU implementácia cut umožňuje použiť iný oddeľovač polí pre výstup pomocou voľby --output-delimiter:
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*Všimnite si, že v takom prípade sú nahradené všetky výskyty oddeľovača polí, a nielen tie na hranici rozsahov špecifikovaných v argumentoch príkazového riadka.
4. Rozšírenia GNU iné ako POSIX
Keď už hovoríme o rozšírení GNU, ktoré nie je POSIX, pár z nich môže byť obzvlášť užitočné. Stojí za zmienku, že nasledujúce rozšírenia fungujú rovnako dobre s rozsahmi bajtov, znakov (čo to znamená v súčasnej implementácii GNU) alebo polí:--complement
Predstavte si túto možnosť ako výkričník v adrese sed (!); namiesto toho, aby sa zachovali údaje zodpovedajúce danému rozsahu, funkcia cut zachová údaje, ktoré sa nezhodujú s rozsahom
# 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)
použite znak NUL ako ukončenie riadku namiesto znaku nového riadku. Možnosť -z je užitočná najmä vtedy, keď vaše údaje môžu obsahovať vložené znaky nového riadku, napríklad pri práci s názvami súborov (keďže nový riadok je platný znak v názve súboru, ale nie NUL).
Aby sme vám ukázali, ako funguje možnosť -z, urobme malý experiment. Najprv vytvoríme súbor, ktorého názov obsahuje vložené nové riadky:
bash$ touchPredpokladajme teraz, že chcem zobraziť prvých 5 znakov každého názvu súboru *.txt. Naivné riešenie tu žalostne zlyhá:
sh$ ls -1 *.txt | cut -c 1-5
BALAN
BALAN
EMPTY
FILE
WITH
NAME.Možno ste si už prečítali, že ls bol navrhnutý pre ľudskú spotrebu a jeho použitie v príkazovom riadku je anti-vzorec (v skutočnosti je). Takže namiesto toho použijeme príkaz find:
sh$ find . -name '*.txt' -printf "%f\n" | cut -c 1-5
BALAN
EMPTY
FILE
WITH
NAME.
BALANa ... to v podstate spôsobilo rovnaký chybný výsledok ako predtým (hoci v inom poradí, pretože ls implicitne triedi názvy súborov, čo príkaz find nerobí).
Problém je v oboch prípadoch v tom, že príkaz cut nedokáže rozlíšiť medzi znakom nového riadku, ktorý je súčasťou dátového poľa (názov súboru), a znakom nového riadka použitým ako koniec značky záznamu. Použitie bajtu NUL (\0) ako ukončovacieho znaku riadku však odstráni zmätok, takže môžeme konečne získať očakávaný výsledok:
# 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
BALANTýmto posledným príkladom sa vzďaľujeme od jadra tohto článku, ktorým bol príkaz cut. Takže, nechám vás, aby ste sa sami pokúsili zistiť význam funky "%f\0" za argumentom printf príkazu find alebo prečo som použil príkaz tr na konci kanála .
Oveľa viac sa dá urobiť pomocou príkazu Vystrihnúť
Práve som ukázal najbežnejšie a podľa mňa najzásadnejšie použitie príkazu Vystrihnúť. Príkaz môžete použiť ešte praktickejšími spôsobmi. Záleží na vašej logickej úvahe a fantázii.
Neváhajte použiť sekciu komentárov nižšie na uverejnenie svojich zistení. A ako vždy, ak sa vám tento článok páči, nezabudnite ho zdieľať na svojich obľúbených webových stránkach a sociálnych sieťach!