awk: Как выбрать несколько подстрок из файла фиксированной длины?

Я искал и искал, но на самом деле не нашел ответа на этот вопрос. Идея состоит в том, что у меня есть файл данных, из которого необходимы некоторые поля данных.

Примеры данных (test.dat)

50DI 20170510144200Mike Tester BL0004992000US 50ELI20170509145200Roy Developer BL0003400020MX 

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

 awk '{print substr($0,3,3)}' test.dat 

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

 #!/bin/bash for i in {1..1}; do a=$(awk '{print substr($0,0,2)}' test.txt) b=$(awk '{print substr($0,20,7)}' test.txt) echo $a, $b done 

что

 50 50, Mike Roy 

вместо

 50, Mike 50, Roy 

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

  • Извлечение столбцов из огромного текстового файла с разделителями
  • Укажите строку Lenth в Awk Pattern Search
  • globbing, sed или awk html-файлы
  • Замена всех ненулевых результатов на «1» для формирования присутствия / отсутствия
  • Печать определенного раздела строки при наличии значения триггера
  • Арифметика по переменной, содержащей ip-адрес
  • путайте с функцией определения пользователя awk
  • Последняя строка неверна при разбиении файла на awk
  • 3 Solutions collect form web for “awk: Как выбрать несколько подстрок из файла фиксированной длины?”

    С GNU awk , если вы действительно хотите фиксированную ширину:

     awk -v FIELDWIDTHS='2 17 7' -v OFS=', ' '{ print $1, $3 }' test.dat 

    С bash :

     while read -r line; do printf '%s, %s\n' "${line:0:2}" "${line:19:7}" done <test.dat 

    С несколько современными sed :

     sed 's/^\(..\).\{17\}\(.\{7\}\).*/\1, \2/' test.dat 

    С perl :

     perl -lpe '$_ = join ", ", unpack "A2x17A7"' test.dat 

    Выход для любого из вышеперечисленного:

     50, Mike 50, Roy 

    Как насчет cut ?

     cut -c1-2,20-26 --output-delimiter ', ' test.dat 50, Mike 50, Roy 

    Метод коротких седов :

     sed -En 's/^(.{2}).{17}(\S+).*/\1, \2/gp' test.dat 

    Выход:

     50, Mike 50, Roy 
    Linux и Unix - лучшая ОС в мире.