私は1000の遺伝子名の短いリストとID番号を含む20000の遺伝子名の完全なリストを持っています。
数値を返すために、リスト全体から短いリストを検索する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
コマンドラインでcatが機能していることを確認してください。FullList
コマンドラインでcatが機能していることを確認してください。- forループがどのように機能するかを確認してください。
echo "${i}"
grep "gene" FullList
コマンドラインからジョブを確認する- 検査された遺伝子は
FullList
ベストアンサー1
最初の変更は、シェルループでこれを行わないことです!つまり、各遺伝子名に対してファイルを一度検索すると、必要なものよりもはるかに長い時間がかかります。代わりに-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の名前の1つがFullListの名前の1つのサブストリングである可能性がある場合、これは非常に遅く、非効率的で、誤った結果を返す可能性があります。結果が得られない場合は、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
入力を続けているため空白行のみが印刷されます。ここでシェルループを使用するもう一つの理由は悪い考えです。