【问题标题】:Prepending text to a specific column in a tab-delimited file?将文本添加到制表符分隔文件中的特定列?
【发布时间】:2012-06-25 18:31:04
【问题描述】:

我有一个这样的文件(制表符分隔),但是很多行

1314    0   0   0   0   0   3   1321    -   k63_1878003 1314    0   1314    6   171115067   64288422    64291057    4   12,131,75,1096, 0,12,143,218,   64288422,64288802,64289161,64289961,

我需要在每行的第 14 列前添加一个 string,但保持其他所有内容相同。我可以在 awk 中这样做还是在 sed 中会更好?

【问题讨论】:

  • 列,如空格分隔?还是在第 14 个字符之前?
  • 什么是列分隔符?或者,列的宽度是否固定(以及宽度是多少?)看起来空格(或制表符)和逗号都可能在使用中。另外,你的前置是什么字符串?

标签: bash sed awk


【解决方案1】:

这可能对你有用(GNU sed):

sed 's/[^\t]*/string&/14' file

【讨论】:

    【解决方案2】:

    使用awk。 OFS 在输出中的字段之间打印一个标签:

    awk 'BEGIN { OFS = "\t" } { $14 = "string" $14; print }' infile
    

    【讨论】:

    • +1 您可以将其缩短为:awk 'BEGIN { OFS = "\t" } $14 = "string" $14' infile,因为赋值为“true”,“true”默认打印$0。
    • 你得到一分,因为你指定设置 OFS,我不太擅长 awk,所以谢谢。
    【解决方案3】:
    $ cat file.txt | sed 's/\(\([^\t]\+\t\)\{13\}\)/\1string/g'
    

    换句话说:用相同的文本替换(([^ ] +){13})(十三个非制表符块,后跟制表符),加上您的string。

    【讨论】:

    • 谢谢,这看起来比awk '{print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8"\t"$9"\t"$10"\t"$11"\t"$12"\t"$13"\t""string"$14"\t"$15"\t"$16"\t"$17"\t"$18"\t"$19"\t"$20"\t"$21}' 更优雅哈哈。也感谢您不问我使用的是什么字符串,因为知道这是一个完全不相关的问题。
    • 哈哈没问题。是的,看看其他答案,似乎awk 更适合这个,但我还不知道如何使用它......所以sed 它是。 :P
    【解决方案4】:

    您可以使用串联来附加到 AWK 中的字段。例如:

    $ echo "foo bar baz" | awk -vOFS=$'\t' '$2 = "quux" $2'
    foo quuxbar baz
    

    在您的情况下,您显然会使用 $13 字段。通过在模式部分而不是操作中进行更改,您只是替换了字段的值并使用该行的默认打印操作。

    【讨论】:

    • @Dan 那是因为您的 OFS 设置不正确。拆分 $0 时,通常需要为制表符分隔符显式指定 OFS。您可以使用 -v 标志或在 BEGIN 块中设置 OFS 来执行此操作。 --我已经更新了示例来展示如何使用 flag 方法来解决这个问题。
    • AWK 理解\t 不需要$''
    • 我的 OFS 设置不正确,因为您没有在您的解决方案中指定我必须这样做。你在我发表评论后编辑了它。
    • @DennisWilliamson 两者都可以;这取决于您希望传达的语义,以及您是否希望 Bash 或 AWK 处理字符扩展。在这个例子中,它肯定是语义上的差异,而不是功能上的差异。 YMMV。
    猜你喜欢
    • 1970-01-01
    • 2018-10-20
    • 2013-07-05
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 2016-08-10
    相关资源
    最近更新 更多