단어 배열과 함께 grep 명령 사용

단어 배열과 함께 grep 명령 사용

몇 줄이 포함된 텍스트 파일이 있고 다음을 사용하여 텍스트 파일을 배열에 저장하고 있습니다.

readarray -t array < Textfile

텍스트 파일에는 다음 내용이 포함되어 있습니다.

123
456
789

이제 grep 명령을 사용하여 배열을 사용하는 다른 텍스트 파일에서 결과를 찾으려고 하므로 "123", "456" 또는 "789"가 나타나는 줄을 인쇄합니다. 배열을 테스트하기 위해 grep에서 동일한 텍스트 파일에서 "123", "456" 및 "789"를 찾아보고 세 문자 시리즈 중 하나 이상이 발생하면 일치하는 줄을 출력해 보았습니다.

나는 노력했다

grep "${array[*]}" Textfile

그러나 이것은 아무런 결과도 보여주지 않습니다. 내가 뭘 잘못했나요?

답변1

첫째, 파일 자체를 사용할 수 있습니다. 이는 쉘 배열을 사용하는 것보다 훨씬 간단합니다.

grep -f file1.txt file2.txt

file2.txt그러면 의 모든 줄과 일치하는 모든 줄 이 인쇄됩니다 file1.txt.

만약 너라면가지다어떤 이유로 배열을 사용하면 상황이 더 복잡해집니다. 배열에서 공백으로 구분된 요소 목록으로 확장되므로 grep "${array[*]}" Textfile이 작업을 수행할 수 없습니다 ."${array[*]}"

$ array=("foo" "bar" "baz")
$ echo "${array[*]}"
foo bar baz

이는 귀하의 grep명령이 다음과 같이 될 것임을 의미합니다.

grep 'foo bar baz' file

foo bar baz이는 "파일에서 찾기 file"를 의미합니다. 당신이하고 싶은 것은 grep 입니다 foo.또는 bar,또는 baz. grep-E 옵션을 사용하고 검색하려는 패턴을 추가하면 됩니다 |.

grep -E 'foo|bar|baz' file

이렇게 하려면 다음과 같은 몇 가지 복잡한 작업을 수행해야 합니다.

grep -E "$(printf '%s|' "${array[@]}" | sed 's/|$//')" file

아마도:

grep -E "$(export IFS="|"; echo "${array[*]}")" file

전반적으로 파일을 사용하고 배열을 잊어버리는 것이 더 좋고, 빠르고, 더 쉽습니다.

답변2

grep "${array[*]}" Textfile

IFSnewline(또는 newline으로 시작하는 모든 것) 으로 설정하고 첫 번째 요소가 newline으로 시작하더라도 계속 작동하는지 확인하는 한 --작동 합니다 .-e-

"${array[*]}"POSIX 쉘에서 와 마찬가지로 Korn 유사 쉘에서는 "$*"의 첫 번째 문자와 연결된 요소 목록으로 확장됩니다 $IFS. $IFS기본값은 <SPC><TAB><NL>( <SPC><TAB><NL><NUL>in zsh)이므로 기본적으로 SPC 문자를 사용하여 요소를 연결합니다. 의 경우 각 정규식을 차례로 반복 grep하려면 여러 정규식을 줄바꿈으로 구분해야 합니다 .grep

IFS=$'\n'
grep -e "${array[*]}" file

에서는 ( 전역 수정 대신 명시적으로 개행 문자 사용 ) 또는 ( / style 에서 배열을 확장하여 여러 모드를 제공하는 또 다른 방법이 됨) zsh을 수행하는 것이 더 깔끔할 것입니다 .grep -e "${(pj:\n:)array}" filej$IFSgrep -e$^array filefishrcgrep -efirst -esecond filegrep

또 다른 옵션은 다음을 수행하는 것입니다.

printf '%s\n' "${array[@]}" | grep -f - file

grep이번에는 개행으로 구분된 패턴 목록이 인수 대신 stdin을 통해 전달됩니다.

-F이러한 방법은 패턴이 고정 문자열(using), 확장 정규식(using -E) 또는 기본 정규식(기본값)인지 여부에 관계없이 작동합니다.

패턴 목록이 비어 있지 않은지 확인해야 할 수도 있습니다.

(( ${#array[@]} > 0 )) && grep ...

grepgrep널 모드로 호출하면 구현 에 따라 다른 결과가 생성되며 일반적으로 원하는 결과가 아닙니다.

관련 정보