Поиск по сайту:

4. Основное и практическое использование команды Cut в Linux


Команда Cut в Linux позволяет удалять данные в каждой строке файла. Прочтите это руководство, чтобы узнать, как эффективно использовать его для обработки текста или файла данных CSV.

Команда вырезания — это канонический инструмент для удаления «столбцов» из текстового файла. В этом контексте «столбец» можно определить как диапазон символов или байтов, идентифицируемых по их физическому положению в строке, или диапазон полей, разделенных разделителем.

Я писал об использовании команд AWK ранее. В этом подробном руководстве я объясню четыре основных и практических примера команды Cut в Linux, которые вам очень помогут.

4 практических примера команды Cut в Linux

Если хотите, вы можете посмотреть это видео, в котором объясняются те же практические примеры команды вырезания, которые я перечислил в статье.

1. Работа с диапазонами символов

При вызове с параметром командной строки -c команда вырезания удалит диапазоны символов.

Как и любой другой фильтр, команда вырезания не меняет входной файл, а копирует измененные данные в стандартный вывод. Вы несете ответственность за перенаправление вывода команды в файл для сохранения результата или за использование канала для отправки его в качестве входных данных для другой команды.

Если вы загрузили образцы тестовых файлов, использованных в видео выше, вы можете увидеть файл данных BALANCE.txt, полученный прямо из бухгалтерской программы, которую моя жена использует на работе:

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

Это текстовый файл фиксированной ширины, поскольку поля данных дополняются переменным количеством пробелов, чтобы обеспечить их отображение в виде хорошо выровненной таблицы.

Как следствие, столбец данных всегда начинается и заканчивается в одной и той же позиции символа в каждой строке. Однако есть небольшая ловушка: несмотря на свое название, команда cut на самом деле требует от вас указать диапазон данных, которые вы хотите сохранить, а не диапазон, который вы хотите удалить. Итак, если мне нужны только столбцы ACCOUNTNUM и ACCOUNTLIB в файле данных выше, я бы написал следующее:

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

Что такое диапазон?

Как мы только что видели, команда вырезания требует, чтобы мы указали диапазон данных, которые мы хотим сохранить. Итак, давайте более формально представим, что такое диапазон: для команды cut диапазон определяется начальной и конечной позициями, разделенными дефисом. Диапазоны отсчитываются от 1, то есть первый элемент строки имеет номер 1, а не 0. Диапазоны являются инклюзивными: начало и конец будут сохранены в выводе, а также все символы между ними. Ошибочно указывать диапазон, конечная позиция которого находится раньше («ниже») его начальной позиции. В качестве сокращения можно опустить начальное или конечное значение, как описано в таблице ниже:

  • a-b: диапазон между a и b (включительно).

  • a: эквивалент диапазона a-a

  • -b: эквивалент 1-a

  • b-: эквивалент b-∞

Команды вырезания позволяют указать несколько диапазонов, разделив их запятой. Вот несколько примеров:

# 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

Одним из ограничений (или особенностей, в зависимости от того, как вы это видите) команды cut является то, что она никогда не меняет порядок данных. Таким образом, следующая команда выдаст точно такой же результат, как и предыдущая, несмотря на то, что диапазоны указаны в другом порядке:

cut -c 93-,-24,36-59 BALANCE.txt

Вы можете легко это проверить с помощью команды 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

Аналогично, команда cut никогда не дублирует данные:

# 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

Стоит упомянуть, что было предложено использовать опцию -o, чтобы снять эти два последних ограничения, позволяя утилите cut изменять порядок или дублировать данные. Но это было отклонено комитетом POSIX«поскольку этот тип усовершенствования выходит за рамки проекта стандарта IEEE P1003.2b. ”

Лично я не знаю ни одной урезанной версии, реализующей это предложение в качестве расширения. Но если да, пожалуйста, поделитесь этим с нами в разделе комментариев!

2. Работа с диапазонами байтов

При вызове с параметром командной строки -b команда вырезания удалит диапазоны байт.

На первый взгляд нет очевидной разницы между диапазонами символов и байтов:

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

Это потому, что мой пример файла данных использует кодировку символов US-ASCII («charset»), поскольку команда file -i может правильно ее угадать:

sh$ file -i BALANCE.txt
BALANCE.txt: text/plain; charset=us-ascii

В этой кодировке символов существует взаимно однозначное соответствие между символами и байтами. Используя только один байт, вы теоретически можете закодировать до 256 различных символов (цифр, букв, знаков препинания, символов и т. д.). На практике это число намного меньше, поскольку кодировки символов предусматривают некоторые специальные значения (например, 32 или 65 управляющих символов). обычно встречается). В любом случае, даже если бы мы могли использовать весь диапазон байтов, этого было бы далеко недостаточно для хранения разнообразия человеческого письма. Итак, сегодня взаимно однозначное сопоставление символов и байтов является скорее исключением, чем нормой, и почти всегда заменяется повсеместной многобайтовой кодировкой UTF-8. Давайте теперь посмотрим, как с этим справится команда Cut.

Работа с многобайтовыми символами

Как я уже говорил ранее, образцы файлов данных, использованные в качестве примеров для этой статьи, взяты из бухгалтерского программного обеспечения, которым пользовалась моя жена. В нем добавлено, что она недавно обновила это программное обеспечение, и после этого экспортированные текстовые файлы немного отличались. Предлагаю вам попробовать заметить разницу самостоятельно:

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

Название этого раздела может помочь вам понять, что изменилось. Но независимо от того, найдено оно или нет, давайте посмотрим теперь на последствия этого изменения:

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

Я скопировал выше вывод команды in-extenso, поэтому должно быть очевидно, что с выравниванием столбцов что-то пошло не так.

Объяснение заключается в том, что исходный файл данных содержал только символы US-ASCII (символы, знаки препинания, цифры и латинские буквы без каких-либо диакритических знаков).

Но если вы внимательно посмотрите на файл, созданный после обновления программного обеспечения, вы увидите, что в новом файле данных экспорта теперь сохраняются буквы с диакритическими знаками. Например, компания под названием «ALNÉENRE» теперь пишется правильно, тогда как ранее она экспортировалась как «ALNEENRE» (без акцента).

Утилита file -i не пропустила это изменение, поскольку теперь сообщает, что файл имеет кодировку UTF-8:

sh$ file -i BALANCE-V2.txt
BALANCE-V2.txt: text/plain; charset=utf-8

Чтобы увидеть, как закодированы буквы с диакритическими знаками в файле UTF-8, мы можем использовать утилиту hexdump, которая позволяет нам просматривать непосредственно байты в файле:

# 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

В строке 00000030 вывода hexdump после нескольких пробелов (байт 20) вы можете увидеть:

  • буква A кодируется как байт 41,

  • буква L кодируется байтом 4c,

  • а буква N кодируется как байт 4e.

Но заглавная ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА E С ОСТРЫМ (так как это официальное название буквы É в стандарте Unicode) кодируется с помощью два байта c3 89

И вот в чем проблема: использование команды cut с диапазонами, выраженными в виде позиций байтов, хорошо работает для кодировок фиксированной длины, но не для кодировок переменной длины, таких как UTF-8 или Shift JIS. Это ясно объяснено в следующем ненормативном отрывке из стандарта POSIX:

Более ранние версии утилиты Cut работали в среде, где байты и символы считались эквивалентными (в некоторых реализациях обработка по модулю и <tab>). В расширенный мир многобайтовых символов добавлена новая опция -b.

Эй, подожди минутку! В приведенном выше «неисправном» примере я использовал не опцию -b, а опцию -c. Итак, не должно ли сработать?!?

Да, должно: к сожалению, мы живем в 2018 году, и, несмотря на это, начиная с GNU Coreutils 8.30, реализация GNU утилиты Cut по-прежнему не обрабатывает несколько -байтовые символы правильно. Цитируя документацию GNU, опция -c выглядит следующим образом: “То же самое, что и -b, но интернационализация изменит это[… ] ” — упоминание, существующее уже более 10 лет!

С другой стороны, реализация утилиты Cut в OpenBSD совместима с POSIX и будет учитывать текущие настройки локали для правильной обработки многобайтовых символов:

# 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

Как и ожидалось, при использовании байтового режима -b вместо символьного режима -c реализация вырезания OpenBSD ведет себя как устаревший 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. Работа с полями

В некотором смысле работать с полями в текстовом файле с разделителями проще с помощью утилиты cut, поскольку ей нужно будет только найти разделители полей (один байт) в каждой строке, скопировав, а затем дословно воспроизведя содержимое поля. на вывод, не беспокоясь о каких-либо проблемах с кодированием.

Вот пример текстового файла с разделителями:

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;

Возможно, вам известен этот формат файла как CSV (значения, разделенные запятыми), даже если разделителем полей не всегда является запятая. Например, точка с запятой (;) часто используется в качестве разделителя полей и часто является выбором по умолчанию при экспорте данных в формате «CSV» в странах, где уже используется запятая в качестве десятичного разделителя ( как мы делаем во Франции — отсюда и выбор этого персонажа в моем файле-примере). Другой популярный вариант использует символ табуляции в качестве разделителя полей, создавая то, что иногда называют файлом значений, разделенных табуляцией. Наконец, в мире Unix и Linux двоеточие (:) является еще одним относительно распространенным разделителем полей, который вы можете встретить, например, в стандартных /etc/passwd и файлы /etc/group.

При использовании формата текстового файла с разделителями вы предоставляете команде вырезания диапазон полей, которые необходимо сохранить, используя параметр -f, и вам необходимо указать разделитель с помощью -d (без параметра -d утилита вырезания по умолчанию использует символ табуляции в качестве разделителя):

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;

Обработка строк, не содержащих разделитель

Но что, если какая-то строка входного файла не содержит разделителя? Заманчиво представить это как строку, содержащую только первое поле. Но это не то, что делает утилита Cut.

По умолчанию при использовании опции -f утилита вырезания всегда дословно выводит строку, не содержащую разделитель (вероятно, предполагая, что это строка, не содержащая данных, например, заголовок или какой-то комментарий). ):

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

Используя опцию -s, вы можете изменить это поведение, поэтому cut всегда будет игнорировать такую строку:

sh$ cut -s -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00
00000001333,00;

Если у вас хакерское настроение, вы можете использовать эту функцию как относительно неясный способ сохранять только строки, содержащие заданный символ:

# Keep lines containing a `e`
sh$ printf "%s\n" {mighty,bold,great}-{condor,monkey,bear} | cut -s -f 1- -d'e'

Изменение выходного разделителя

В качестве расширения реализация Cut в GNU позволяет использовать другой разделитель полей для вывода с помощью опции --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*

Обратите внимание: в этом случае заменяются все вхождения разделителя полей, а не только те, которые находятся на границе диапазонов, указанных в аргументах командной строки.

4. Расширения GNU, не относящиеся к POSIX.

Говоря о расширениях GNU, не относящихся к POSIX, пара из них может оказаться особенно полезной. Стоит отметить, что следующие расширения одинаково хорошо работают с байтовыми, символьными (что это означает в текущей реализации GNU) или диапазонами полей:--complement

Думайте об этом параметре как о восклицательном знаке в адресе sed (!); вместо того, чтобы сохранять данные в соответствии с заданным диапазоном, cut будет сохранять данные, НЕ соответствующие диапазону

# 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;

--оканчивается нулем (-z)

используйте символ NUL в качестве признака конца строки вместо символа новой строки. Опция -z особенно полезна, когда ваши данные могут содержать встроенные символы новой строки, например, при работе с именами файлов (поскольку новая строка является допустимым символом в имени файла, а NUL — нет).

Чтобы показать вам, как работает опция -z, давайте проведем небольшой эксперимент. Сначала мы создадим файл, имя которого будет содержать вставленные новые строки:

bash$ touch

Давайте теперь предположим, что я хочу отобразить первые 5 символов каждого имени файла *.txt. Наивное решение здесь с треском провалится:

sh$ ls -1 *.txt | cut -c 1-5
BALAN
BALAN
EMPTY
FILE
WITH
NAME.

Возможно, вы уже читали, что ls был разработан для использования человеком, и его использование в командном конвейере является антишаблоном (это действительно так). Поэтому давайте вместо этого воспользуемся командой find:

sh$ find . -name '*.txt' -printf "%f\n" | cut -c 1-5
BALAN
EMPTY
FILE
WITH
NAME.
BALAN

и… это привело, по сути, к тому же ошибочному результату, что и раньше (хотя и в другом порядке, поскольку ls неявно сортирует имена файлов, чего не делает команда find).

Проблема в том, что в обоих случаях команда cut не может отличить символ новой строки, являющийся частью поля данных (имени файла), и символ новой строки, используемый в качестве маркера конца записи. Но использование нулевого байта (\0) в качестве признака конца строки устраняет путаницу, и мы наконец можем получить ожидаемый результат:

# 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

В этом последнем примере мы отходим от сути этой статьи — команды cut. Итак, я позволю вам попытаться самостоятельно понять значение необычного "%f\0" после аргумента printf команды find или почему я использовал команду tr в конце конвейера. .

С помощью команды «Вырезать» можно сделать гораздо больше.

Я только что показал наиболее распространенное и, на мой взгляд, самое важное использование команды «Вырезать». Вы можете применить команду еще более практичными способами. Это зависит от вашего логического рассуждения и воображения.

Не стесняйтесь использовать раздел комментариев ниже, чтобы опубликовать свои выводы. И, как всегда, если вам понравилась эта статья, не забудьте поделиться ею на своих любимых сайтах и в социальных сетях!

Статьи по данной тематике: