我需要按照给定关键字文件中指定的顺序从 Excel 文件 (.xls) 中提取包含 row 的关键字。例如,我有一个 excel 文件,即基因组.xls,如下所示,
NC_0208.1 18918 94692 amyl4_A0A0H 1 54 194
NC_0208.1 18839 86123 prot4_A0A0 1 79 137
NC_0208.4 29761 74985 lip10_H8FLU5 2 393 48
NC_0208.2 29687 67745 lysin6_A0A0Q5 5 38 49
我有一个关键字文件,即 id.txt,如下所示,
prot
lip
cellulase
lysin
amyl
预期输出是
NC_0208.1 18839 86123 prot4_A0A0 1 79 137
NC_0208.4 29761 74985 lip10_H8FLU5 2 393 48
NC_0208.2 29687 67745 lysin6_A0A0Q5 5 38 49
NC_0208.1 18918 94692 amyl4_A0A0H 1 54 194
除此之外,如果基因组文件中不存在关键字,则应在输出文件中将整行保留为空。为了做到这一点,我使用了 grep 命令,如下所示,
grep 'prot\|lip\|cellulase\|lysin\|amyl' genome.xls > result.xls
上述命令是提取包含整行的关键字,但顺序已更改。此外,它不会为缺失的关键词留下空行。因此,请帮助我做同样的事情。提前致谢。
答案1
尝试这个,
while read a ; do grep "$a" genome.xls || printf "\n" ; done < id.txt
NC_0208.1 18839 86123 prot4_A0A0 1 79 137
NC_0208.4 29761 74985 lip10_H8FLU5 2 393 48
NC_0208.2 29687 67745 lysin6_A0A0Q5 5 38 49
NC_0208.1 18918 94692 amyl4_A0A0H 1 54 194
答案2
我认为您的要求需要对关键字进行循环。我推荐以下 shell 脚本(尽管如果您愿意,您可以将其吸收为一行):
#!/bin/bash
while read keyword
do
# Apply grep, but store result in variable
MATCH="$(grep $keyword genome.xls)"
# If grep result is an empty string, output an empty line,
# otherwise the grep result as-is.
if [[ -z "$MATCH" ]]
then
echo
else
echo "$MATCH"
fi
done < id.txt
通过循环内容id.txt
可以确保输出的顺序。
调用脚本
user@host$ ./extract_lines.sh > result.xml
为了使脚本更加灵活,我们可以将要处理的文件设置为命令行参数,甚至是命令行参数列表:
#!/bin/bash
if [[ "$#" == "0" ]]
then
echo "Usage: $0 <filename(s)>"
exit 1
fi
for file in "$@"
do
outfile=${file/.xls/_result.xls}
:>$outfile
echo "Process $file, write results to $outfile"
while read keyword
do
# Apply grep, but store result in variable
MATCH="$(grep $keyword $file)"
# If grep result is an empty string, output an empty line,
# otherwise the grep result as-is.
if [[ -z "$MATCH" ]]
then
echo "" >> $outfile
else
echo "$MATCH" >> $outfile
fi
done < id.txt
done
这将循环指定为命令行参数(并且是 it *.xls
)的所有文件并将结果写入<input_filename>_result.xls
.
笔记然而,这种语法有点初级,因为您不应该*
在参数列表中将文件名规范与“glob”(即通配符,如 )和常规文件名混合使用。