当在这些行中找到相同的单词时,组合来自不同文件的两行

时间:2016-02-17 18:06:27

标签: bash

我是bash的新手,当我在这些行中找到相同的单词时,我想要合并来自不同文件的两行。

E.g:

文件1:

 organism 1
  1 NC_001350
  4 NC_001403

 organism 2
  1 NC_001461
  1 NC_001499

文件2:

  NC_001499 » Abelson murine leukemia virus
  NC_001461 » Bovine viral diarrhea virus 1
  NC_001403 » Fujinami sarcoma virus
  NC_001350 » Saimiriine herpesvirus 2 complete genome
  NC_022266 » Simian adenovirus 18
  NC_028107 » Simian adenovirus 19 strain AA153

我想要一个输出:

文件3:

 organism 1
  1 NC_001350 » Saimiriine herpesvirus 2 complete genome
  4 NC_001403 » Fujinami sarcoma virus

 organism 2
  1 NC_001461 » Bovine viral diarrhea virus 1
  1 NC_001499 » Abelson murine leukemia virus

有没有办法获得类似输出的东西?

4 个答案:

答案 0 :(得分:0)

你可以得到与你想要的输出非常相似的东西:

awk 'NR == FNR { a[$1] = $0; next } 
    { print $1, ($2 in a ? a[$2] : $2) }' file2 file1

使用第一个字段作为键,将file2的每一行读入数组a。然后对file1中的每一行打印第一个字段,然后打印a中的匹配行(如果找到一个),否则打印第二个字段。

如果间距很重要,那么这需要更多努力,但完全有可能。

答案 1 :(得分:0)

我们可以从第二个文件创建一个sed脚本并将其应用到第一个文件。它很简单,我们使用sed s命令从每一行构造另一个sed s命令并存储在一个变量中供以后使用:

 sc=$(sed -rn 's#^\s+(\w+)([^\w]+)(.*)$#s/\1/\1\2\3/g;#g; p;' file2 )
 sed "$sc" file1

第一个命令看起来很奇怪,因为我们在外部 sed #中使用了s,我们在中使用了更常见的/内部 sed s命令作为分隔符。

执行echo $sc来研究内部。它只是将file2的每一行的各部分放入不同的捕获组,然后将捕获的字符串与s/find/replace/g;合并为

  • find is \1
  • 替换为\1\2\3

答案 2 :(得分:0)

对于更多Bash 4 ish解决方案:

declare -A descriptions

while read line; do
  name=$(echo "$line" | cut -d '»' -f 1 | xargs echo)
  description=$(echo "$line" | cut -d '»' -f 2)
  eval "descriptions['$name']=' »$description'"
done < file2

while read line; do
  name=$(echo "$line" | cut -d ' ' -f 2)
  if [[ -n "$name" && -n "${descriptions[$name]}" ]]; then
    echo "${line}${descriptions[$name]}"
  else
    echo "$line"
  fi
done < file1

答案 3 :(得分:0)

您希望将file2重建为sed命令文件。

sed 's# \(\w\+\) \(.*\)#s/\1/\1 \2/#' File2

您可以使用进程替换来使用结果,而不将其存储在临时文件中。

sed -f <(sed 's# \(\w\+\) \(.*\)#s/\1/\1 \2/#' File2) File1