Bash 当在不同文件的两行中找到相同的单词时,将它们组合起来

Bash 当在不同文件的两行中找到相同的单词时,将它们组合起来,bash,Bash,我是bash新手,我希望在不同文件的两行中找到相同的单词时,将它们组合起来 例如: 文件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 sarco

我是bash新手,我希望在不同文件的两行中找到相同的单词时,将它们组合起来

例如:

文件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

有什么方法可以得到类似的输出吗?

您可以得到与所需输出非常相似的输出,如下所示:

awk 'NR == FNR { a[$1] = $0; next } 
    { print $1, ($2 in a ? a[$2] : $2) }' file2 file1
这将使用第一个字段作为键,将
file2
的每一行读入数组
a
。然后,对于
file1
中的每一行,如果找到一行,则打印第一个字段,后跟
a
中的匹配行,否则打印第二个字段


如果间距很重要,那么就需要付出更多的努力,但这是完全可能的。

我们可以从第二个文件创建一个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带有

  • 查找是
    \1
  • 替换为
    \1\2\3

有关更多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
declare-A描述
读行时;做
名称=$(回显“$line”|剪切-d'»-f 1 | xargs回显)
描述=$(回显“$线”|切割-d'»-f 2)
评估“描述['$name']='»$description''
完成<文件2
读行时;做
名称=$(回显“$行”|切割-d'-f 2)
如果[[-n“$name”&&&n“${descriptions[$name]}”];然后
回显“${line}${descriptions[$name]}”
其他的
回音“$line”
fi
完成<文件1

您想将文件2重建为sed命令文件

sed 's# \(\w\+\) \(.*\)#s/\1/\1 \2/#' File2
您可以使用进程替换来使用结果,而无需将其存储在临时文件中

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

sed-f非常感谢您!这真的帮助了我!