【问题标题】:Bash: replacing a column by another and using AWK to print specific orderBash:用另一列替换一列并使用 AWK 打印特定顺序
【发布时间】:2017-11-28 14:47:02
【问题描述】:

我有一个看起来像这样的虚拟文件:

a ID_1 S1 S2
b SNP1 1 0
c SNP2 2 1
d SNP3 1 0

我想用相应的行号替换第 2 列的内容。我的文件将如下所示:

a 1 S1 S2
b 2 1 0
c 3 2 1
d 4 1 0

我可以使用以下命令来做到这一点:

cut -f 1,3-4 -d " " file.txt | awk '{print $1 " " FNR " " $2,$3}'

我的问题是,有没有更好的方法来做到这一点?特别是,我正在处理的真实文件有 2303 列。显然我不想写:

cut -f 1,3-2303 -d " " file.txt | awk '{print $1 " " FNR " " $2,$3,$4,$5 ETC}'

有没有办法告诉 awk 从第 2 列打印到最后一列而不必写下所有名称?

谢谢

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    我认为应该这样做

    $ awk '{$2=FNR} 1' file.txt 
    a 1 S1 S2
    b 2 1 0
    c 3 2 1
    d 4 1 0
    

    更改第二列并打印更改的记录。默认的 OFS 是单个空格,这正是您在这里所需要的


    上面的命令是惯用的写法

    awk '{$2=FNR} {print $0}' file.txt 
    

    你可以把简单的awk程序想象成awk 'cond1{action1} cond2{action2} ...'

    仅当cond1 的计算结果为真时,action1 才会被执行,依此类推。如果action 部分被省略,awk 默认打印输入记录。 1 只是编写永远为真条件的一种方式

    查看https://stackoverflow.com/tags/awk/info中提到的Idiomatic awk了解更多此类成语

    【讨论】:

    • 太好了,它有效!快速提问,{} 之外的 1 是什么意思?
    • 一切都是“代码”,所以为了清楚起见,用“action1”等替换“code1”等。
    【解决方案2】:

    关注awk 在这里也可能对您有所帮助。

    awk '{sub(/.*/,FNR,$2)} 1'  Input_file
    

    输出如下。

    a 1 S1 S2
    b 2 1 0
    c 3 2 1
    d 4 1 0
    

    解释: 解释很简单,使用awksub 实用程序将$2(第二个字段)中的所有内容替换为FNR awk 的开箱即用变量表示任何 Input_file 的当前行号,然后提及 1 将打印 Input_file 的当前行。

    【讨论】:

    • 没有理由偏爱sub(/.*/,FNR,$2) 而不是$2=FNR,输出将是相同的,但 sub() 会使您的代码变慢。
    • 谢谢,这也很好知道,我不知道这个子实用程序!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 2021-11-17
    • 2013-10-26
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多