我是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
有没有办法获得类似输出的东西?
答案 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;
合并为
\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