【问题标题】:Subtracting from values ending with specific digits?从以特定数字结尾的值中减去?
【发布时间】:2022-01-14 03:57:55
【问题描述】:

我有一个如下所示的 .bed (.tsv) 文件:

chr1    0   100000
chr1    100000  200000
chr1    200000  300000
chr1    300000  425234

我想使用 sed 或 awk 仅从第 3 列中以“000”结尾的值执行操作 -1,以便输出如下所示:

chr1    0   99999
chr1    100000  199999
chr1    200000  299999
chr1    300000  425234

令人尴尬的是,我想出的最好的方法是:


awk {sub(/000$/,"999",$3); print $1,$2,$3}' oldfile > newfile

它只是将最后 3 位数字替换为 999,而不是实际减去。 任何帮助都是值得赞赏的!

【问题讨论】:

    标签: awk sed


    【解决方案1】:

    Awk 也可以轻松执行算术运算。

    awk 'BEGIN{FS=OFS="\t"} $3 ~ /000$/ {$3 -= 1}1' oldfile > newfile
    

    这是假设文件中的所有行始终包含三个字段,并且您要打印所有行。

    sed 连最简单的算术都不知道,所以它不是特别适合这个。

    【讨论】:

    • @EdMorton 感谢您的编辑,我总是设法通过忘记OFS 来打自己的脚。
    • 是的,这是一个常见的错误。在一个完美的世界中,-F 将同时设置 FS(也将重命名为 IFS)和 OFS,但是 - 现在我们已经 40 年了,这不会发生......
    【解决方案2】:

    我将为此使用 GNU AWK,如下所示,让 file.txt 内容为

    chr1    0   100000
    chr1    100000  200000
    chr1    200000  300000
    chr1    300000  425234
    

    然后

    awk 'BEGIN{OFS="\t"}($3%1000==0){$3-=1}{print}' file.txt
    

    输出

    chr1    0   99999
    chr1    100000  199999
    chr1    200000  299999
    chr1    300000  425234
    

    说明:使用制表符 (\t) 作为输出字段分隔符 (OFS)。如果将$31000 相乘的余数为零(即$31000 的乘积),则对于每一行print,从$3 中减去1

    (在 gawk 4.2.1 中测试)

    【讨论】:

    • $3%1000 的结果是一个浮点数(请参阅gnu.org/software/gawk/manual/…),所以我想知道在输入是 1000 的倍数的情况下,它是否保证始终完全等于零。我真的不知道不知道。
    猜你喜欢
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 2020-09-24
    • 1970-01-01
    • 2015-07-27
    • 2022-06-10
    • 2016-12-07
    相关资源
    最近更新 更多