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,00

Toto 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é rozsahu a-a

  • -b: ekvivalentné s 1-a

  • b-: ekvivalentné s b-∞

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.txt

Môž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 identical

Podobne 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
5

Za 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 identical

Je 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-ascii

V 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,83

Skopí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-8

Ak 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              |           .|
0000007c

Na riadku 00000030 výstupu hexdump po hromade medzier (bajt 20) môžete vidieť:

  • písmeno A je zakódované ako bajt 41,

  • písmeno L je zakódované a bajt 4c,

  • a písmeno N je zakódované ako bajt 4e.

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,83

Ako 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,83

3. 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,00

Pomocou 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$ touch

Predpokladajme 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.
BALAN

a ... 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
BALAN

Tý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!

Súvisiace články: