bash在文件中循环查找字符串的开头

时间:2019-05-31 19:45:09

标签: bash awk

我有一个带有约10,000行数据的大文本文件,因此每一行可能有不同数量的列。例如:

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
...
...

我想遍历每一行并提取出其中出现前缀“ P00 *”的第二列。例如,在文件的上述代码段中,我想要:

KGOX P0002
KMNO P0001

与线790和799相对应。列数是完全随机的,并且可以从一行更改为另一行。最重要的是,在该行的某处,某些文本列以“ P00”开头。

我有一个简单的while读取循环:

 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 个答案:

答案 0 :(得分:5)

使用GNU sed:

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

输出:

KGOX P0002
KMNO P0001

答案 1 :(得分:3)

您可以使用awk

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

这将搜索模式“ P00*直到下一个空格,并将其存储到名为“ a”的数组中。

注意:GNU awk是运行此功能所必需的。

答案 2 :(得分:2)

另一个简单的awk脚本(标准Linux gawk

awk 'match($0,/P000[^ ]+/,a){print $2, a[0]}' input.txt

答案 3 :(得分:1)

看看您的输入,也许您可​​以选择:

grep 'P00.' | cut -d' ' -f2

答案 4 :(得分:1)

获取第二列是棘手的部分,因为它并不总是位于同一位置。正则表达式有一些更好的答案(匹配功能非常方便),但是蛮力的方法是先打印第二个字段,然后在当前行上每隔一个字段打印出来,然后找到与P00匹配的字段。

awk '{fld2=$2 ; split($0, a) ; for (f in a) { print fld2 " " a[f] } }' t | grep 'P00*'
KGOX P0002
KMNO P0001