我有 1000 个基因名称的简短列表和 20000 个带有 ID 号的基因名称的完整列表。
我尝试设置一个 for 循环来搜索完整列表中较短的列表以返回数字。
这是代码:
#/bin/bash
LIST=$(cat ShortList.txt)
for i in ${LIST}
do
RESULT=$(grep -i ${i} FullList.txt)
echo "${RESULT}" >> Final_List_With_Numbers
done
生成的文件是空的 - 关于更改内容有什么建议吗?
非常感谢您的帮助!
我已经完成了一些故障排除:
- 检查猫
Shortlist
在命令行中工作 - 检查猫
FullList
在命令行中工作 - 检查 for 循环的工作原理
echo "${i}"
grep "gene" FullList
在命令行中检查工作- 检查的基因在
FullList
答案1
第一个更改是不要在 shell 循环中执行此操作!这意味着您对每个基因名称搜索一次文件,并且将花费比必要的时间长得多的时间。相反,使用-f
选项grep
将名称列表作为输入:
grep -iFxf ShortList.txt FullList.txt > Final_List_With_Numbers
使用的选项是:
-i, --ignore-case
Ignore case distinctions in patterns and input data,
so that characters that differ only in case match each other.
-F, --fixed-strings
Interpret PATTERNS as fixed strings, not regular expressions.
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. If this option is
used multiple times or is combined with the -e (--regexp) option,
search for all patterns given. The empty file contains zero patterns,
and therefore matches nothing.
-x, --line-regexp
Select only those matches that exactly match the whole line.
For a regular expression pattern, this is like parenthesizing
the pattern and then surrounding it with ^ and $.
这-x
尤其重要,因为您不想LOC12345
在搜索时找到LOC1
.但是,如果您FullList.txt
没有仅有的每行的基因名称,那么您可能想使用-w
而不是-x
:
-w, --word-regexp
Select only those lines containing matches that form whole words. The test is that the
matching substring must either be at the beginning of the line, or preceded by a non-word
constituent character. Similarly, it must be either at the end of the line or followed by a
non-word constituent character. Word-constituent characters are letters, digits, and the
underscore. This option has no effect if -x is also specified.
现在,您显示的代码应该可以实际工作。如果 Shortlist 中的名称之一可以是 FullList 中的名称之一的子字符串,那么它会非常非常慢且低效,并且可能会返回错误的结果。如果您从未得到任何结果,我猜测您是ShortList.txt
在 Windows 中创建的并且具有 Windows 样式的行结尾 ( \r\n
)。这意味着循环i
中的每个for i in ${LIST}
都不会geneName
,而是geneName\r
不存在,FullList.txt
因此找不到结果。
如果您在 *nix 文件上进行测试,它将按预期工作:
$ cat ShortList.txt
name1
name2
name3
$ cat FullList.txt
name3
name4
现在,在这些示例上运行您的确切代码:
$ LIST=$(cat ShortList.txt); for i in ${LIST}; do
RESULT=$(grep -i ${i} FullList.txt);
echo "${RESULT}" >> Final_List_With_Numbers;
done
$ cat Final_List_With_Numbers
name3
当然,它也包含空行,因为当您找不到匹配项时,$RESULT
它是空的,但您仍在echo
ing 它,这意味着只会打印空行。这里使用 shell 循环是一个坏主意的另一个原因。