Bash цикл по файлу, чтобы найти начало строки - PullRequest
3 голосов
/ 31 мая 2019

У меня большой текстовый файл с ~ 10000 строк данных, причем каждая строка может иметь разное количество столбцов.Например:

789 KKPP 2018 08 09 10 20 30 AUTO A2987 10SM 5-MIN 22/13
790 KGOX 2018 08 09 10 20 35 AUTO P0002 21/19
...
798 KLXZ 2018 08 09 10 20 40 AUTO 18013GT 7SM 21/16 RMK A02 T02060156
799 KMNO 2018 08 09 10 20 45 AUTO 10SM P0001
...
...

Я хочу перебрать каждую строку и извлечь 2-й столбец, в котором появляется префикс "P00 *".Например, в приведенном выше фрагменте файла я хотел бы:

KGOX P0002
KMNO P0001

, которые соответствуют строкам 790 и 799. Число столбцов является абсолютно случайным и может меняться от одной строки к следующей.,Самое важное, что где-то в строке какой-то столбец текста начинается с «P00».

У меня есть простой цикл чтения:

 while IFS='' read -r line || [[ -n "${line}" ]];
 do
 temp=$(echo ${line} | awk '{print $7}')
 if [[ ${temp:0:3} == "P00" ]];
 then
 data=${temp}
 fi
 done

Но это быстро запутывается,так как номера столбцов могут превышать 30. Есть ли более простой способ получить эту информацию и, возможно, записать в текстовый файл?Я знаю, что awk может делать что-то, что может работать, но не может заставить что-либо работать должным образом.

Ответы [ 5 ]

5 голосов
/ 31 мая 2019

С GNU sed:

sed -En 's/^[^ ]+ ([^ ]+).*( P00[^ ]*).*/\1\2/p' file

Выход:

KGOX P0002
KMNO P0001
4 голосов
/ 31 мая 2019

В вы можете использовать awk:

awk '{match($0,/.*(P000[^ ]+).*/,a)} a[1]{print $2,a[1] }' input
KGOX P0002
KMNO P0001

Это будет искать шаблон "P00* до следующего пробела и сохранять его в массив с именем" a ".

Примечание: GNU awk требуется для того, чтобы это работало.

2 голосов
/ 31 мая 2019

Еще один простой awk скрипт (стандартный Linux gawk)

awk 'match($0,/P000[^ ]+/,a){print $2, a[0]}' input.txt
1 голос
/ 31 мая 2019

Получение 2-го столбца - сложная часть, поскольку она не всегда находится в одном и том же месте. Есть несколько лучших ответов с регулярными выражениями (функция соответствия очень удобна), но подход грубой силы состоит в том, чтобы напечатать поле два, за которым следуют все остальные поля в текущей строке, а затем найти те, которые соответствуют P00.

awk '{fld2=$2 ; split($0, a) ; for (f in a) { print fld2 " " a[f] } }' t | grep 'P00*'
KGOX P0002
KMNO P0001
1 голос
/ 31 мая 2019

Глядя на ваш вклад, может быть, вы могли бы просто пойти с:

grep 'P00.' | cut -d' ' -f2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...