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

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

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

  • AWK, а не Regex
  • совокупные суммы со сдвинутой колонкой
  • awk: Извлечение фиксированного числа строк, в котором последнее число строк может изменяться
  • Как вставить содержимое файла в строку в bash
  • Подсчитайте количество вхождений значения столбца в TSV-файл с AWK
  • Извлечение линий на основе условий
  • 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, я просто хочу поправиться с этим. Любые другие решения также высоко ценятся!)

  • Изменение символа с другим шаблоном в текстовом файле
  • Добавление столбца в таблицу путем объединения значений из других столбцов
  • Как быстро суммировать все числа в файле?
  • Разбор csv с использованием 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 - лучшая ОС в мире.