2개의 파일이 있는데 둘 다 줄이 많지만 숫자만 포함되어 있습니다. file1의 숫자가 file2의 숫자와 일치하는지 확인하려고 합니다. 이것이 내가 시도한 것이지만 어떤 이유로 작동하지 않습니다.
for i in $(cat file1); do grep ${i} file2; done
이전 참조는 file1과 file2의 데이터입니다.
file1 file2
2134 1251
2135 5626
5342 4327
6456 8453
3413 4537
4525 3533
2347 5738
1235 1235
7453 3462
그렇다면 이 명령은 파일 1의 모든 줄을 가져와 전체 파일 2로 grep하면 안 되나요? 이런 경우, 일치하는 내용이 화면에 인쇄되어서는 안되는 것인가요?
답변1
그냥 사용해야하거나 grep -f file1 file2
사용할 수도 있습니다cat file1 | grep -f /dev/stdin file2
답변2
두 개의 일반 Unix 텍스트 파일이 주어지면 쉘 루프가 인쇄됩니다.
1235
이는 두 파일 모두에 나타나는 줄이기 때문입니다. 그렇지 않은 경우 파일 중 하나가 DOS 텍스트 파일일 수 있습니다. 이 유틸리티를 사용하여 DOS 텍스트 파일을 Unix 텍스트 파일로 변환할 수 있습니다 dos2unix
.
grep
한 번만 호출한다는 점을 제외하면 보유한 데이터 유형을 고려할 때 루프에 큰 문제는 없습니다.모든line in . in file1
과 같은 하위 문자열과도 일치하며 , 줄에 공백이나 탭이 포함되어 있으면 해당 줄을 여러 단어로 분할합니다( 따옴표 로 묶지 않기 때문 ).100
1001
file1
for i in $(cat ...)
$(cat ...)
문제를 해결하고 싶다면이것방법(루프 포함), 이렇게 하는 것이 좋습니다
while IFS= read -r word; do
grep -xF -e "$word" file2
done <file1
나중에 내 대답에서 설명하고 다음 인수가 일치하는 패턴이라고 말합니다. 그렇지 않으면 대시()로 시작하면 명령줄 -x
옵션으로 처리될 수 있습니다.-F
-e
-
이 작업은 grep
의 각 행에 대해 한 번씩 실행되지만 file1
올바르게 실행됩니다.
file2
쉘 루프를 사용하지 않고 라인과 정확히 일치하는 라인을 추출하려면 file1
다음을 사용할 수 있습니다.
$ grep -xF -f file1 file2
1235
이는 file1
다음을 포함 한다고 가정합니다.합리적인줄 수는 있지만 너무 많지는 않습니다("너무 많다"는 것은 메모리 양에 따라 달라집니다).
이 명령은 전체 행에서만 일치를 강제하는(하위 문자열 일치 없음) grep
with 를 사용하고 정규식 일치 대신 문자열 비교를 수행하도록 변경 합니다.-x
-F
grep
-f file1
( 일치 할 문자열 grep
) 에서 읽을 패턴을 나타냅니다 file1
.
정말 많은 양의 데이터의 경우 사용 효율성이 매우 비효율적입니다 grep
. 대신, 이 작업과 이러한 유형의 데이터(별도의 줄에 있는 단일 단어)의 경우 파일 간에 관계형 조인 작업을 수행하는 것이 좋습니다.
$ join file1 file2
1235
이것은,두 파일이 모두 사전순으로 정렬되어 있다고 가정합니다., 두 파일 사이에 동일한 숫자를 반환합니다.
사용 comm
:
$ comm -1 -2 file1 file2
1235
comm
그래도 상대적으로정렬됨파일을 쉽게 처리할 수 있습니다.매우대규모 데이터 세트. 기본적으로 세 개의 열을 인쇄합니다.
- 첫 번째 파일에만 나타나는 줄
- 두 번째 파일에 나타나는 줄만
- 두 파일 모두에 나타나는 줄
-1
첫 번째 열의 출력을 끄고 두 -2
번째 열을 비활성화하여 comm
두 파일 모두에서 동일한 줄만 출력합니다.