如何搜索两个模式并根据结果写出不同的行

时间:2014-07-28 16:06:38

标签: unix awk sed scripting grep

我有两万多个存档文件来搜索某个模式,并希望从结果中输出每个文件的第四行。是的文件是否可以使用grep?

数据如下所示:

UNA:+.? '
UNB+UNOC:1+XXX:ZZ+ZZZ:14+140726:0215+AA000083308210++INVOIC'
UNH+1+INVOIC:D:98A:UN'
BGM+380+4161846758'
DTM+3:20140725:102'
DTM+140:20140908:102'
RFF+ON:4501161623'
NAD+SU+2024241::90++WSWSInternational bvba/sprl        +DeereResearchpark Zone 3:Geldenaaksebaan 464:B-XCXCLeuven, BELGIUM:.++++BE'
RFF+VA:BE0403593343'
RFF+VR:2024241'
NAD+PS+5050083901044::9++Wimble Manufacturing Belgium BVBA+:::EGGESTR 1++++BE'
RFF+VA:BE0838369020'
NAD+DP+::9++LABO PRINGLES+:::HOMBEEKSESTWG 323'
CUX+2:EUR:4'

所以,我想搜索NAD + SU,NAD + PS,如果可以找到“+ :::”,则写入新文件或打印包含BGM的行,这总是第4行。 感谢

3 个答案:

答案 0 :(得分:0)

find . -name 'archived.files.pattern' -print0 |
while read -d '' -r filename; do
    if grep -Eq '^NAD\+(SU|PS).*\+:::' "$filename"; then
        sed -n '4{p;q}' "$filename"
    fi
done

使用find打印"归档文件列表" - 有20 000个文件,可能会得到"参数列表太长"错误。假设GNU找到-print0动作。

答案 1 :(得分:0)

对于多字符RS的GNU awk,这应该这样做:

$ awk -v RS='^$' -F'\n' '/(^|\n)NAD\+(SU|PS)[^\n]*\+:::/{ print FILENAME, $4 }' file1 ... file20000

或者如果您愿意:

$ find <whatever> | xargs awk -v RS='^$' -F'\n' '/(^|\n)NAD\+(SU|PS)[^\n]*\+:::/{ print FILENAME, $4 }'

如果您不需要在每个输出行之前打印文件名,请删除FILENAME,。如果文件名可以包含换行符,请使用find <whatever> -print0 | xargs -0 awk...

答案 2 :(得分:0)

这是一个awk脚本(包含多个文件)来自find:

find . -name 'file.pattern' -execdir awk '
  FNR==4 {bgm = $0}
  FNR==8 && index($0, "+:::") ||
  FNR==11 && index($0, "+:::") {print bgm}
' {} +

awk脚本很简单,假设行号不会在文件之间发生变化。如果他们这样做,请替换Ed Morton的剧本。