从列值等于pattern

时间:2018-10-24 19:59:34

标签: bash

文件具有相同的头,包括许多列和仅一行。首先,我提取了标头并将其保存到newA.txt和newB.txt。接下来,我需要从每个文件中提取第21列与模式A00 [1-9]匹配的行,在第21列与模式B00 [1-9]匹配的行,而不包括第21列与A00 [1-9]匹配的行。模式A00 [1-9] _B00 [1-9]。这些行将附加到它们各自的文本文件中:A模式附加到newA.txt,B模式附加到newB.txt。请注意,与模式匹配的行数是未知的,模式的最后一个数字在1-9之间变化,并且在某些文本文件中的标题之后可能没有任何行。

下面的示例是到目前为止我已经完成的工作,但是显然不是我想要的。这只会打印出A模式的列值,不包括标题。

FILES=exp.var1.*.cat.out
for f in $FILES; do
    cat $f | tail -n +2 | awk '$21 ~ /^A00[0-9]/ { print $21 }'
done

打印的内容如下:

A001
A001_B001

文本文件具有以表格分隔的列,并且行数只能等于1(仅标题),也可以等于很多(标题加1或多个A或B模式以及A _B < / em>模式)。

2 个答案:

答案 0 :(得分:0)

您应该可以将正则表达式更改为/^[AB]00[0-9]$/以获得所需的匹配项。

答案 1 :(得分:0)

类似的东西应该起作用

$ awk '$21 ~ /^A00[1-9]_B00[1-9]/ {next}
       $21 ~ /^A00[1-9]/          {print > "newA.txt"}
       $21 ~ /^B00[1-9]/          {print > "newB.txt"}' exp.var1.*.cat.out

将跳过组合模式匹配的行,否则将匹配的行发送到相应的文件。无需循环访问文件。

或者,更容易通过以下内容扩展到其他字符(不确定是否有用例?)

$ awk '$21 ~ /^A00[1-9]_B00[1-9]/ {next}
       $21 ~ /^[AB]00[1-9]/ {print > ("new" substr($21,1,1) ".txt")}' exp.var1.*.cat.out

如果标题可能匹配,则可以将FNR==1 ||添加到我们跳过该行的第一个条件。

显然没有经过测试。...