【问题标题】:Process multiple files and append them in linux/unix处理多个文件并将它们附加到 linux/unix
【发布时间】:2016-07-08 20:56:26
【问题描述】:

我有超过 100 个文件,每个文件至少有 5-8 列(制表符分隔)。我需要从每个文件中提取前三列,并在第四列中添加一些预定义的文本并附加它们。

假设我有 3 个文件:file001.txtfile002.txtfile003.txt

file001.txt:

chr1 1 2 15
chr2 3 4 17

file002.txt:

chr1 1 2 15
chr2 3 4 17

file003.txt:

chr1 1 2 15
chr2 3 4 17

combined_file.txt:

chr1 1 2 f1
chr2 3 4 f1
chr1 1 2 f2
chr2 3 4 f2
chr1 1 2 f3
chr2 3 4 f3

为简单起见,我保持文件内容相同。 我的脚本如下:

#!/bin/bash
for i in {1..3}; do
j=$(printf '%03d' $i)
awk 'BEGIN { OFS="\t"}; {print $1,$2,$3}' file${j}.txt | awk -v k="$j" 'BEGIN {print $0"\t$k”}' | cat >> combined_file.txt
done

但脚本给出以下错误:

awk: 非终止字符串 $k”}... 在源代码第 1 行 上下文是

有人能帮我弄清楚吗?

【问题讨论】:

  • 你有一个问题陈述,再加上你有一个 bash 脚本解决(我假设)是你问题的一部分。你被困在哪里了?我错过了一个问题。它也与您的 file00.txt 混淆,其中所有文件都具有完全相同的内容。
  • @mattias,帖子已编辑。
  • 你在这里混合了一些特殊字符。请注意 BEGIN 语句 'BEGIN {print $0"\t$k”}' 中“和”之间的区别。这应该可以让您摆脱遇到的错误。但是您可能在 awk 命令中遇到其他问题。
  • @mattias,谢谢。它现在正在工作,但将第四列打印为 $k 而不是它的值。
  • 使用 echo $k 而不是 BEGIN {print $0"\t$k"}

标签: linux awk cat


【解决方案1】:

您不需要两个不同的awk 脚本。并且你不要使用$ 来引用awk 中的变量,它是用来引用输入字段的(即$k 表示访问编号在变量k 中的字段)。

for i in {1..3}; do
    j=$(printf '%03d' $i)
    awk -v k="$j" -v OFS='\t' '{print $1, $2, $3, k}' file$j.txt
done > combined_file.txt

【讨论】:

  • 谢谢。它工作正常。我刚刚在打印中添加了 k。
【解决方案2】:

正如 cmets 中指出的那样,您的问题是您尝试使用奇数字符,就好像它们是双引号一样。但是,一旦您解决了这个问题,您就不需要循环或任何其他复杂性,您所需要的只是:

$ awk 'BEGIN{FS=OFS="\t"} {$NF="f"ARGIND} 1' file*
chr1    1       2       f1
chr2    3       4       f1
chr1    1       2       f2
chr2    3       4       f2
chr1    1       2       f3
chr2    3       4       f3

上面使用了 GNU awk 作为 ARGIND。

【讨论】:

  • 谢谢。你能解释一下细节吗?
  • 当然——你不明白哪一部分?如果你只是想开始学习 awk,我强烈推荐 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书。
  • 不客气。如果/当您找到适合您的答案时,请记住单击您接受的答案旁边的复选标记。见stackoverflow.com/help/someone-answers
猜你喜欢
  • 2023-03-02
  • 1970-01-01
  • 2017-02-08
  • 2015-05-15
  • 1970-01-01
  • 2012-09-17
  • 2019-08-10
  • 1970-01-01
  • 2012-05-19
相关资源
最近更新 更多