【问题标题】:replace specific columns on lines not starting with specific character in a text file替换文本文件中不以特定字符开头的行上的特定列
【发布时间】:2020-06-12 23:17:37
【问题描述】:

我有一个如下所示的文本文件:

>long_name
AAC-TGA
>long_name2
CCTGGAA

还有一个列号列表:2, 4, 7。当然,我可以将这些作为变量,例如:

cols="2 4 7"

我需要将不以> 开头的行的每一列替换为单个字符,例如N,以得到:

>long_name
ANCNTGN
>long_name2
CNTNGAN

其他详细信息 - 该文件有大约 200K 行。所有不以> 开头的行都是相同的长度。行索引永远不会超过非> 行的长度。

在我看来,sed 和 awk 的某种组合必须能够快速完成此操作,但我终其一生都无法弄清楚如何将它们链接在一起。

例如我可以使用 sed 处理所有不以 > 开头的行(在这种情况下,用 N 替换所有空格):

sed -i.bak '/^[^>]/s/ /N/g' input.txt

而且我可以使用 AWK 来替换特定的行列,因为我想要这样(我认为...):

awk '$2=N'

但我正在努力将它缝合在一起

【问题讨论】:

  • 在使用 awk 时永远不需要 sed。

标签: unix awk sed


【解决方案1】:

使用 GNU awk,将 i/o 字段分隔符设置为空字符串,以便每个字符成为一个字段,您可以轻松地更新它们。

awk -v cols='2 4 7' '
BEGIN {
  split(cols,f)
  FS=OFS=""
}
!/^>/ {
  for (i in f)
    $(f[i])="N"
}
1' file

另见Save modifications in place with awk

【讨论】:

    【解决方案2】:

    您可以先生成替换命令列表,然后将它们传递给sed

    $ printf '2 4 7' | sed -E 's|[0-9]+|/^>/! s/./N/&\n|g'
    /^>/! s/./N/2
     /^>/! s/./N/4
     /^>/! s/./N/7
    $ printf '2, 4, 7' | sed -E 's|[^0-9]*([0-9]+)[^0-9]*|/^>/! s/./N/\1\n|g'
    /^>/! s/./N/2
    /^>/! s/./N/4
    /^>/! s/./N/7
    
    $ sed -f <(printf '2 4 7' | sed -E 's|[0-9]+|/^>/! s/./N/&\n|g') ip.txt
    >long_name
    ANCNTGN
    >long_name2
    CNTNGAN
    


    也可以使用{}分组

    $ printf '2 4 7' | sed -E 's|^|/^>/!{|; s|[0-9]+|s/./N/&; |g; s|$|}|'
    /^>/!{s/./N/2;  s/./N/4;  s/./N/7; } 
    

    【讨论】:

    • 您可以将 seds -e-f 混合一次或多次,-f 接受 - 作为标准输入,因此 &lt;&lt;&lt;'2 4 7' sed -E 's#\S+#s/./N/&amp;\n#g' | sed -e '/^&gt;/b' -f - file 将获得相同的结果。
    【解决方案3】:

    在每个 UNIX 机器上的任何 shell 中使用任何 awk:

    $ awk -v cols='2 4 7' '
        BEGIN { split(cols,c) }
        !/^>/ { for (i in c) $0=substr($0,1,c[i]-1) "N" substr($0,c[i]+1) }
    1' file
    >long_name
    ANCNTGN
    >long_name2
    CNTNGAN
    

    【讨论】:

      猜你喜欢
      • 2017-01-16
      • 1970-01-01
      • 2017-01-27
      • 2016-08-28
      • 2021-03-23
      • 2021-05-01
      • 1970-01-01
      • 2020-11-12
      相关资源
      最近更新 更多