【问题标题】:Change field separator with awk or sed of a specific set of columns使用一组特定列的 awk 或 sed 更改字段分隔符
【发布时间】:2020-11-05 11:42:20
【问题描述】:

我想修改一个同时使用制表符和空格作为字段分隔符的文件。 一开始我们有一个具有这种结构的文件:

 chr1    Cufflinks    gene_id "XLOC_000001"; oId "XR_003076322.1";
 chr1    Cufflinks    gene_id "XLOC_000012"; oId "XR_001548508";

执行awk -F' ' '$4=$6 {print $0}' 执行我正在寻找的(将“gene_id”的值更改为“oId”中的值):

 chr1 Cufflinks gene_id "XR_003076322.1"; oId "XR_003076322.1";
 chr1 Cufflinks gene_id "XR_001548508"; oId "XR_001548508";

问题在于它改变了行结构:chr1Cufflinksgene_id 之间的标签 \t 消失了。我尝试添加-v OFS=\t,但它会将制表符放在gene_id "XLOC_000012"; oId "XR_001548508"; 部分(应该用空格分隔)。我也尝试过使用sed 类似sed -i 's/ /\t/' 的东西,但它也到处都是标签。

如何将第 1 列的字段分隔符更改为第 3 列(并且不要将第 3 列更改为第 6 列)?

【问题讨论】:

  • 您的条件$4=$6 实际上不是一个条件,= 是一个赋值运算符,所以您要比较 $4 和 $6 吗?或者您想将第 4 个字段值指定为第 6 个字段?请确认一次。
  • 不,这不是条件,这是故意的。我需要将 $6 的值分配给 $4

标签: awk sed


【解决方案1】:

使用 awk 的可能性:

awk -F '[ ]' '{$2 = $4; print}' file

通过使用空格字符作为输入字段分隔符(与空格和制表符相反),可以在不将制表符更改为空格的情况下分配字段。

对于更复杂的情况,有split(但没有“join”):

awk 'BEGIN {FS=OFS="\t"} {n = split($3, a, " "); a[2] = a[4]; for (i=1; i<=n; ++i)
    $3 = (i == 1 ? "" : $3 " ") a[i]
} 1' file

【讨论】:

    【解决方案2】:

    您可以使用此sed 来保留您的空格:

    sed -E $'s/^([ \t]*([^ \t]+[ \t]+){3})[^ \t]+([ \t]+)(([^ \t]+[ \t]+){1})([^ \t]+)/\\1\\6\\3\\4\\6/' ff
    
    chr1    Cufflinks    gene_id "XR_003076322.1"; oId "XR_003076322.1";
    chr1    Cufflinks    gene_id "XR_001548508"; oId "XR_001548508";
    

    将第 6 个字段复制到第 4 个字段的说明:

    • ^: #比赛开始
    • ([ \t]*([^ \t]+[ \t]+){3}): # 匹配前 4-1 个字段并在组 #1 中捕获
    • [^ \t]+: #匹配第4个字段
    • ([ \t]+): # 匹配第 4 个字段后的空格并在第 3 组中捕获
    • (([^ \t]+[ \t]+){1}): # 匹配下一个 (6-4-1) 字段并在组 #4 中捕获
    • ([^ \t]+): # 匹配第 6 个字段并在第 6 组中捕获
    • \\1\\6\\3\\4\\6: 将反向引用放回去替换

    或者,这个awk 也创建一个表格对齐的输出:

    awk '$4=$6' file | column -t
    
    chr1  Cufflinks  gene_id  "XR_003076322.1";  oId  "XR_003076322.1";
    chr1  Cufflinks  gene_id  "XR_001548508";    oId  "XR_001548508";
    

    【讨论】:

    • 谢谢,第一个答案是正确的,但第二个答案不正确,因为它将标签放在任何地方。你能解释一下sed命令吗?我需要将其调整为包含超过 15 列的更复杂的文件
    • 我将在我的sed 命令中添加解释。是的,第二个不会保留原始空格,但会创建新的表格格式。
    • 非常感谢这些解释 :) 它工作正常
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多