Команда «Вырезать» не извлекает поля должным образом в выровненных столбцах

Команда «Вырезать» не извлекает поля должным образом в выровненных столбцах

У меня есть текстовый файл, в котором мне нужно вырезать поля 3,4,5 и 8:

219 432 4567 Harrison     Joel     M 4540 Accountant      09-12-1985
219 433 4587 Mitchell     Barbara  C 4541 Admin Asst      12-14-1995
219 433 3589 Olson        Timothy  H 4544 Supervisor      06-30-1983
219 433 4591 Moore        Sarah    H 4500 Dept Manager    08-01-1978
219 431 4527 Polk         John     S 4520 Accountant      09-22-1998
219 432 4567 Harrison     Joel     M 4540 Accountant      09-12-1985
219 432 1557 Harrison     James    M 4544 Supervisor      01-07-2000

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

cut -f 3,4,5,8 filename

Дело в том, что вывод такой же, как и исходное содержимое файла. Что здесь происходит? Почему это не работает?

решение1

Не все эти пробелы между столбцами выглядят как табуляции, поэтому cutне получится сделать то, что вы хотите. Я бы предложил использовать awkвместо этого. Это более гибко, чем cutпри разборе столбцов данных, например, того, чего вы пытаетесь добиться:

$ awk '{print $3,$4,$5,$8}' data.txt

Пример

$ awk '{print $3,$4,$5,$8}' data.txt 
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor

Вы также можете разбить вывод на интервалы, используя columnкоманду:

$ awk '{print $3,$4,$5,$8}' data.txt |column -t
4567  Harrison  Joel     Accountant
4587  Mitchell  Barbara  Admin
3589  Olson     Timothy  Supervisor
4591  Moore     Sarah    Dept
4527  Polk      John     Accountant
4567  Harrison  Joel     Accountant
1557  Harrison  James    Supervisor

Вы также можете сделать все, используя только awkи printf:

$ awk '{printf "%s\t%-20s\t%s\n",$3,$4" "$5,$8}' data.txt 
4567    Harrison Joel           Accountant
4587    Mitchell Barbara        Admin
3589    Olson Timothy           Supervisor
4591    Moore Sarah             Dept
4527    Polk John               Accountant
4567    Harrison Joel           Accountant
1557    Harrison James          Supervisor

вырезать пересмотрено

Вышеуказанные методы работают нормально, но они не обрабатывают ни одну из строк, где есть пробелы в значении для определенного столбца. Например, строка с "Dept Manager" обрезается до просто Dept.

Если можно гарантировать, что данные будут иметь такую ​​структуру, как показано, мы могли бы использовать ее, cutно вместо разделения по разделителю мы могли бы просто отображать данные, используя фактические позиции символов.

Пример

Это позволит вырезать текст из data.txtфайла и напечатать то, что находится в позициях с 9 по 13, с 14 по 35 и т. д.

$ cut -c 9-13,14-35,43-58 data.txt 
4567 Harrison     Joel     Accountant      
4587 Mitchell     Barbara  Admin Asst      
3589 Olson        Timothy  Supervisor      
4591 Moore        Sarah    Dept Manager    
4527 Polk         John     Accountant      
4567 Harrison     Joel     Accountant      
1557 Harrison     James    Supervisor      

awk снова посещен

Awk также можно заставить вытаскивать текст на основе его позиции, а не разделителя. Это более многословно, но вот как, просто для полноты.

$ awk '{
    printf "%s\t%-20s\t%s\n",substr($0,9,5),substr($0,14,22),substr($0,43,16)
  }' data.txt
4567    Harrison     Joel       Accountant      
4587    Mitchell     Barbara    Admin Asst      
3589    Olson        Timothy    Supervisor      
4591    Moore        Sarah      Dept Manager    
4527    Polk         John       Accountant      
4567    Harrison     Joel       Accountant      
1557    Harrison     James      Supervisor      

ШИРИНА ПОЛЯ awk

Если вы используете вариант GNU, awkвы можете использовать переменную FIELDWIDTHSдля указания статического размера каждого поля. Это работает намного чище, чем substrметод, если у вас есть к нему доступ. Также вы можете эффективно склеивать поля, которые в противном случае были бы проанализированы как отдельные поля.

$ awk 'BEGIN { FIELDWIDTHS="4 4 5 24 5 16 11" }{ print $3,$4,$5,$6 }' data.txt 
4567  Harrison     Joel     M  4540  Accountant      
4587  Mitchell     Barbara  C  4541  Admin Asst      
3589  Olson        Timothy  H  4544  Supervisor      
4591  Moore        Sarah    H  4500  Dept Manager    
4527  Polk         John     S  4520  Accountant      
4567  Harrison     Joel     M  4540  Accountant      
1557  Harrison     James    M  4544  Supervisor      

решение2

Я предполагаю, что я не думаю, что это вкладки. Причина, по которой я не думаю, что это вкладки, заключается в том, что когда я копирую-вставляю файл и вручную табулирую поля, то, cut -f 3,4,5,8 filenameпохоже, все работает нормально. Вам может быть лучше сделать это, cat filename | awk '{print $3, $4, $5, $8}'если вы не хотите повторно табулировать поля и значения.

Связанный контент