나는 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에 있는 이름 중 하나가 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
입력 중이므로 빈 줄만 인쇄됩니다. 여기서 쉘 루프를 사용하는 또 다른 이유는 나쁜 생각입니다.