在特定列中,编辑不等于 3 个可能变量中任何一个的行,最好在 awk 中

在特定列中,编辑不等于 3 个可能变量中任何一个的行,最好在 awk 中

在特定列中,我需要将行替换为“X”,但前提是它们与 3 个可能的模式(3 个变量)中的任何一个都不匹配。请注意,该列并不总是相同的列,因此代码必须在列号本身是可变数字的情况下工作。对于 3 种可能的模式也可以这样说。如果没有演示,很难解释。在示例中,如果您查看第 1 列并了解它如何根据“GrabVariantOption”将特定的内容更改为“X”,那么它可能比我能解释的任何内容都更清楚。

输入示例:

A,A,A,X
A,G,T,X
C,A,G,T
A,C,G,T
f,X,A,g
g,T,A,A
m,s,G,A
G,s,m,A

示例 3 可能的模式:

GrabVariantOption1=A
GrabVariantOption2=g
GrabVariantOption3=G

一些伪代码,这就是我想要做的原则:

Column=1   

awk -F ',' -v a=$GrabVariantOption1 -v b=$GrabVariantOption2 -v c=$GrabVariantOption3 -v x=$Column '{$x; if NR!=a && NR!=b && NR!=c; flag=1} {if flag=1 NR==X }'

示例输出:

A,A,A,X
A,G,T,X
X,A,G,T
A,C,G,T
X,X,A,g
g,T,A,A
X,s,G,A
G,s,m,A

答案1

awk -F, -v OFS=, \
  -v "a=$GrabVariantOption1" \
  -v "b=$GrabVariantOption2" \
  -v "c=$GrabVariantOption3" \
  -v "x=$Column" '
  $x != a && $x != b && $x != c {$x = "X"}
  {print}'

或者这里是单个 ASCII 字母:

awk -F, -v OFS=, \
  -v "pattern=^[$GrabVariantOption1$GrabVariantOption2$GrabVariantOption3]\$" \
  -v "x=$Column" '
  $x !~ pattern {$x = "X"}
  {print}'

NR是一个特殊变量,awk保存当前记录号(此处的行号带有默认记录分隔符)。$是取消引用字段的运算符。因此,如果x字段编号为您提供第 th$ x字段的内容。x

答案2

另外一个选择:

awk -v col=1 -v keys="$GrabVariantOption1,$GrabVariantOption2,$GrabVariantOption3" '
    BEGIN {
        FS = OFS = ","

        # keys is a single string: "A,g,G"

        n = split(keys, a)

        # now, n=3 and a is the array ("A", "g", "G")

        for (i=1; i<=n; i++) keep[a[i]] = 1

        # now, keep is an associative array mapping "A"=>1, "g"=>1, "G"=>1
        # ("A" in keep) is true
        # ("C" in keep) is false
    }
    !($col in keep) {$col = "X"}
    {print}
' input

答案3

尝试这个,

awk -F ',' -v a=$GrabVariantOption1 -v b=$GrabVariantOption2 -v c=$GrabVariantOption3 -v x=$Column -v OFS=',' '{if (($x != 'a') && ($x != 'b') && ($x != 'c')) {$x="X"}; print }' input.txt 
A,A,A,X
A,G,T,X
X,A,G,T
A,C,G,T
X,X,A,g
g,T,A,A
X,s,G,A
G,s,m,A

答案4

以下是使用扩展正则表达式的 Gnu sed 查看 pbm 的一种方法:

$ col=1 opt1=G opt2=g opt3=G
$ opt=${opt1}${opt2}${opt3}
$ sed -Ee "
   s/^/,/
   s/(([^,]*,){$col})[^$opt]/\1X/
   s/,//
" file.csv

使用 Perl 你也可以这样做:

$ perl -lpe "
   s/^/,/;
   substr(\$_,2*$col-1,1) =~ tr/$opt/X/c;
   s/,//;
" file.csv

相关内容