【问题标题】:Execute bash command inside awk and print command output在 awk 中执行 bash 命令并打印命令输出
【发布时间】:2018-01-16 05:32:11
【问题描述】:

给定一个文件test.txt,其内容如下:

ABC DEF GATTAG GHK
ABC DEF GGCGTC GHK 
ABC DEF AATTCC GHK

需要修改第3列,使字符串为反向补码。其中一部分可以通过 bash 命令完成:

cat test.txt | cut -f3 | rev | tr ATGC TACG

CTAATC
GACGCC
GGAATT

如何使用awk 来实现? (有一个更大的 awk 脚本用于处理文件,将添加此功能。) p>

一种可能的方法是在awk 内部执行rev | tr ATGC TACG,类似于:

awk '{newVar=system("rev | tr ATGC TACG"$3); print $1 $2 newVar $4}' test.txt

但是,此版本和各种类似版本不起作用。谁能指出不正确的地方?

【问题讨论】:

    标签: awk system getline


    【解决方案1】:

    只需在 awk 本身中进行字符串反转和翻译:

    $ awk '
        BEGIN {
            old="ATGC"
            new="TACG"
            for (i=1;i<=length(old);i++) {
                tr[substr(old,i,1)] = substr(new,i,1)
            }
        }
        {
            newVar=""
            for (i=1;i<=length($3);i++) {
                char = substr($3,i,1)
                newVar = (char in tr ? tr[char] : char) newVar
            }
            print $1, $2, newVar, $4
        }
    ' file
    ABC DEF CTAATC GHK
    ABC DEF GACGCC GHK
    ABC DEF GGAATT GHK
    

    如果你真的觉得迫切需要从 awk 调用一个外部工具并读回结果,那就是:

    $ awk '
        {
            cmd="echo \047" $3 "\047 | rev | tr \047ATGC\047 \047TACG\047"
            newVar=((cmd | getline line) > 0 ? line : "failed")
            close(cmd)
            print $1, $2, newVar, $4
        }
    ' file
    ABC DEF CTAATC GHK
    ABC DEF GACGCC GHK
    ABC DEF GGAATT GHK
    

    但您应该期望这样做会对性能产生重大影响,另请参阅 getline 警告:http://awk.freeshell.org/AllAboutGetline

    【讨论】:

    • 是的,我注意到它在大约一个月前消失了。在 awk.info 消失后,我开始使用该参考。也许最好在我实际发布它的 comp.lang.awk usenet 组的 google 组视图中引用它:groups.google.com/forum/message/raw?msg=comp.lang.awk/…
    • 建议:可以在这里创建一个 github repo 或 gist 或类似的,或社区 wiki ..
    • 是的,我考虑过了。实际上,我曾经在 freeservers 上有一些东西,有一堆 awk 脚本配方,但是一夜之间就消失了,我没有追求它。然后它在 awk.info 上消失了,现在 awk.freeshell.org 也消失了。人生太短了……
    【解决方案2】:

    如果perl 没问题:

    $ perl -lane '$F[2]=~tr/ATGC/TACG/; $F[2]=reverse $F[2]; print "@F"' test.txt 
    ABC DEF CTAATC GHK
    ABC DEF GACGCC GHK
    ABC DEF GGAATT GHK
    
    • -a 选项将在空格处拆分行并保存到 @F 数组
    • $F[2]=~tr/ATGC/TACG/ 仅在第三列使用 tr
    • $F[2]=reverse $F[2] 反转第三列的字符串
    • print "@F" 打印修改后的数组,以空格为分隔符

    也可以写成
    perl -lane '$F[2]=reverse $F[2]=~tr/ATGC/TACG/r; print "@F"' test.txt 
    

    或在替换部分使用 Perl 代码

    perl -pe 's/^(\H+\h+){2}\K\H+/reverse $&=~tr|ATGC|TACG|r/e' test.txt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 2011-12-11
      • 1970-01-01
      • 2013-06-10
      相关资源
      最近更新 更多