【问题标题】:replace zero with text using sed or awk使用 sed 或 awk 将零替换为文本
【发布时间】:2013-10-30 20:35:17
【问题描述】:

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

 0  chr23:54039     0   54039
 0  chr23:103278    0   103278
 0  chr22:174609    0   174609
 0  chr22:54039     0   54039
 0  chr25:103278    0   103278
 0  chr25:174609    0   174609
 26 chr26:174609    0   174609

如果第一列是“0”,我需要将第一列中的 0 替换为 chr 后面的数字。因此,输出应如下所示:

23  chr23:54039     0   54039
23  chr23:103278    0   103278
22  chr22:174609    0   174609
22  chr22:54039     0   54039
25  chr25:103278    0   103278
25  chr25:174609    0   174609
26  chr26:174609    0   174609

谁能提供一个简单的 sed 或 awk 任何 linux 解决方案?

【问题讨论】:

    标签: sed awk


    【解决方案1】:

    如果第 1 列中的数字始终与 chr 数字相同,您可以使用 awk 执行此操作

    awk '{split($2,a,":|chr");$1=a[2]}1' file
    23 chr23:54039 0 54039
    23 chr23:103278 0 103278
    22 chr22:174609 0 174609
    22 chr22:54039 0 54039
    25 chr25:103278 0 103278
    25 chr25:174609 0 174609
    26 chr26:174609 0 174609
    

    【讨论】:

    • @Jotne:+1 表示优雅和深入了解 awk 的使用。我对 awk 了解得越多,我就越喜欢它(具有多个分隔符的能力,或者在 :"chr" 上具有 split 的能力非常高效和强大。)
    • @Oliver:谢谢你的提醒 :)。 awk 非常强大,当你认为你见过最多的时候,它的新用法就会浮出水面。
    • 请注意,这会重新创建整个第一列,即它不会像 OP 所要求的那样仅更改第一列中带有“0”的行。 [它似乎是同一件事,举个小例子,因为它似乎 OP的文件已经从第二个字段中获取了一些值......但它可能是只是这个例子的巧合?]。添加条件将是一个简单的调整:只需在{ 之前添加/^0 / ,这样更改(拆分等)只会在以“0”开头的行发生。
    • 它在我的帖子中声明。这可以通过使用 !$1 像这样 awk '!$1 {split($2,a,":|chr");$1=a[2]}1' 启动 awk 来解决
    【解决方案2】:

    使用 sed:

    $ sed -r '/^0/s/0(\s*chr)([^:]*)/\2\1\2/g' file
    23  chr23:54039     0   54039
    23  chr23:103278    0   103278
    22  chr22:174609    0   174609
    22  chr22:54039     0   54039
    25  chr25:103278    0   103278
    25  chr25:174609    0   174609
    26 chr26:174609    0   174609
    

    没有-r

    $ sed '/^0/s/0\(\s*chr\)\([^:]*\)/\2\1\2/g' file
    23  chr23:54039     0   54039
    23  chr23:103278    0   103278
    22  chr22:174609    0   174609
    22  chr22:54039     0   54039
    25  chr25:103278    0   103278
    25  chr25:174609    0   174609
    26 chr26:174609    0   174609
    

    这个想法是替换以0 开头的行。在其中,0...chrNUM:... 被捕获并以所需格式打印回来。

    awk:

    $ awk '/^0/ {split($2,a,":"); gsub("chr", "", a[1]); $1=a[1]}1' file
    23 chr23:54039 0 54039
    23 chr23:103278 0 103278
    22 chr22:174609 0 174609
    22 chr22:54039 0 54039
    25 chr25:103278 0 103278
    25 chr25:174609 0 174609
    26 chr26:174609    0   174609
    

    给定以0 开头的行,第二个字段由: 分隔符分成几部分,然后删除chr 文本。然后它就可以存储为第一个字段了。 1 使条件为真,因此将打印完整的新行。

    【讨论】:

    • @realspirituals 检查所有版本
    • @realspirituals 请注意,OP 输入在每行之前都有一个空格。我在测试中删除了它,因为我猜这是一个错误。
    • 删除前导 WS 后,这三个都可以正常工作。谢谢老兄。
    • @OlivierDulac 谢谢。请注意,添加空格 /^0 / 不是最终解决方案,因为它可能有一个制表符而不是空格。 /^0/FS 会更好,在BEGIN{} 组中会设置字段分隔符。
    • @fedorqui: 或者简单地说:($1 == "0")?
    【解决方案3】:
    sed "s/^0[[:blank:]]\{1,\}chr\([0-9]\{1,\}\):/\1 chr\1:/"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-03
      • 1970-01-01
      • 2018-07-02
      • 2010-10-27
      • 2013-05-30
      • 2021-10-25
      相关资源
      最近更新 更多