비슷한 답변을 검색했지만 부분 일치 문제를 해결한 답변이 없습니다. 스키마 파일은 file2이고 삭제할 행은 file1.csv에 있습니다. 이는 여기에 표시된 것보다 더 많은 열이 포함된 상당히 큰 파일입니다.
file1.csv에 다음 필드가 있습니다.
고쳐 쓰다:
Linking page,Last crawled
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://imgcop.com/img/Bwin-Mobile-App-77898390/,"Nov 17, 2018"
https://start.me/site/unibet.be?locale=fr,"Nov 17, 2018"
https://poker.partypoker402.com/en/blog/matt-savage-talks-wpt500.html,"Nov 17, 2018"
파일 2에는 다음이 포함됩니다.
https://roulette2.tk
paradisebingo.t
paradisebingo.tm
free-bwin.ro
sb288.co
OUTPUT
Linking page,Last crawled
Linking page,Last crawled
Linking page,Last crawled
Linking page,Last crawled
Linking page,Last crawled
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
etc....
출력이 반복됩니다. 무엇이 잘못되었는지 잘 모르겠습니다.
awk 'FNR == NR{ neg[$1]; next } { for ( i in neg ) if ( $1 !~ i) print }' file2.txt FPAT='([^,]*)|("[^"]+")' file1.csv > out.csv
하지만 제대로 작동하지 못했습니다. 이상한 이유로 grep이 실패합니다.
grep -vwF -f file2 file1.csv > output.csv
답변1
당신이 한 일은 좋은 시도처럼 보이지만 정규식 일치 절이 원하는 방식으로 작동하지 않습니다. 에서는 찾으려는 값이 $2 !~ neg[$1]
두 번째 파일에서 검색됩니다 .file1
neg['156398439']
$1
아니요첫 번째. 따라서 귀하의 상태는 결코 일치하지 않습니다.
file1
반복을 통해 작업 섹션 내에서 정규식 비교를 수행하기 위해 이와 같은 작업을 수행할 수 있습니다.
awk 'FNR == NR { neg[$1]; next }{ for ( i in neg ) if ( $2 !~ i) print }' file2 FS="," file1
FS
또한 이렇게 복잡한 정규식을 사용하여 CSV 파일의 제한을 해제할 수는 없을 것 같습니다 FS
. 필드를 정의하는 방법이 아니라 분할할 제한 해제자를 정의하는 것을 기억하세요. 필드가 어떻게 생겼는지 설명하는 표현이 있는 것 같습니다. GNU에서는 awk
다른 변수가 FPAT
이러한 정규식을 정의할 수 있도록 허용합니다.
당신은 그것을 사용할 수 있습니다
awk 'FNR == NR { neg[$1]; next }{ for ( i in neg ) if ( $2 !~ i) print }' file2 FPAT='([^,]*)|("[^"]+")' file1
답변2
이니안의 대답file2
한 줄만 길면 잘 작동하며 보다 일반적인 답변을 시작하는 데 좋습니다. 하지만 난 믿어요
awk 'FNR == NR { neg[$1]; next } { ok=1; for (i in neg) if ($2 ~ i) ok=0; if (ok) print }' file2 FS="," file1
일반적으로 당신이 원하는 것을 할 것입니다. 답변과 마찬가지로 먼저 file2
내용(에서 제거하려는 패턴 file
)을 읽고 배열에 저장합니다. Inian의 답변처럼 다음과 같습니다 file1
. 의 각 행에 대해 의 file1
패턴을 반복합니다 file2
. 우리는 라인이 괜찮다고 가정합니다. 어떤 패턴과 일치하면 그렇지 않습니다. 모든 패턴을 확인 후 문제가 없을 경우 인쇄해 드립니다.
FS=","
그러나 나는 그것을 Inian이 하는 일이기 때문에 와 사이의 논쟁 으로 삼았습니다 . 아무것도 상관없어file2
file1
에프생산하다에스읽을 때 사용하는 구분 기호 file2
는 표시되지 않고 file2
쉼표를 포함하지 않는 한입니다. 따라서 "일반적인" 방식으로 필드 구분 기호를 지정하여 위의 내용을 약간 단순화할 수 있습니다. -F
명령 시작 부분에 옵션을 추가하면 됩니다.
앗-에프,'FNR == NR { 부정 [$1]; 다음} { OK=1 for (i in neg) if ($2 ~ i) ok=0 if (OK) print}' file2 file1
-F","
원하는 경우 이를 사용할 수 있습니다.
이 테스트는 FNR == NR
너무 대중적이고 흔해서 우리는 아무 생각 없이 사용합니다.
FNR
줄 번호(일명 레코드 번호)입니다.현재 파일에서는NR
줄 번호 입니다모든 입력에 걸쳐. 예를 들어,
$ cat cats
Felix
Garfield
Heathcliff
$ cat dogs
Lassie
Marmaduke
Snoopy
$ awk '{ print FNR, NR, $0 }' cats dogs
1 1 Felix
2 2 Garfield
3 3 Heathcliff
1 4 Lassie
2 5 Marmaduke
3 6 Snoopy
…따라서 처리할 첫 번째 파일의 각 줄 FNR
에 대한 합계는 동일하며 후속 파일에서는 동일하지 않습니다. NR
그래서 우리는 이를 사용하여 FNR == NR
첫 번째 파일이 처리되고 있는지 테스트합니다.
그러나 이것은 실제로 나쁜 습관입니다. 첫 번째 파일이 비어 있으면 어떻게 되나요?
$ cat unicorns
$ wc unicorns
0 0 0 unicorns
$ awk '{ print FNR, NR, $0 }' unicorns dogs
1 1 Lassie
2 2 Marmaduke
3 3 Snoopy
FNR == NR
그건 진실이야첫 번째 파일의 경우실제로 데이터가 있습니다. 당신 file2
의 의지가 결코 비어 있지 않다면 이 질문을 무시할 수 있을 것입니다. 그러나 문제의 정의에 따르면 비어 있으면 아무것도 제거하지 않으므로 file2
출력은 all 이 되어야 합니다 . file1
그러나 아무것도 없이 위의 명령을 실행하면 다음과 같은 결과 file2
가 나타납니다.아니요 왜냐하면 실제로 두 번째 파일( )을 읽을 때 첫 번째 파일 awk
( )을 읽고 있다고 생각하기 때문입니다.file2
file1
더 안전한 접근 방식은 파일 매개변수 사이에 값을 할당하는 것입니다.
awk -F, '문서! = 2{ 부정 [$1]; 다음} { ok=1; for (i in neg) if ($2 ~ i) ok=0 if (ok) 인쇄}' 파일파일=2파일 1
이 질문은 약간 모호합니다. "부분 일치"란 무엇을 의미합니까?정확히? Inian은 질문이 제안한 의미로 해석하기로 결정했습니다 grep
. file2
두 번째 열의 값과 일치하는 값이 있는 경우file1
정규식으로는,
그런 다음 해당 줄을 삭제하십시오 file1
. 하지만 두 가지 문제가 있습니다.
놀라운 요인. 질문에 있는 파일을 가져와서 추가했습니다.
154376352,"http://sb288eco.tm","example4"
에 줄을 서서
file1
첫 번째 명령을 실행합니다. (from )이 정규 표현식으로 처리되기 때문에 이"example4"
줄은 출력되지 않습니다 (여기서sb288.co
file2
.
"모든 문자와 일치"를 의미함), matchsb288eco
.이것이 당신이 원하고 기대하는 일이라면 지금 이 글을 읽지 않는 것이 좋습니다.
- 정규식 처리에는 계산 비용이 많이 듭니다. 정규식은 구문 분석되고 처리되어야 합니다. 이는 단순한 문자열 비교보다 시간이 더 걸릴 수 있습니다.
위의 두 가지 문제를 테스트하여 해결할 수 있습니다.끈from 이 awk 함수의 file2
from 값에 존재합니다.file1
index
awk -F, 'FILE != 2 { neg[$1];next} { OK=1;for (i는 음수입니다)if(index($2,i)>0)OK=0; if (ok) 인쇄 }' file2 FILE=2 file1
요약하자면,.
게임 file2
에는 딱 하나밖에 없습니다..
file1
, 다른 문자가 아닌 . 귀하의 데이터에 대해 위의 내용을 테스트하고 속도가 더 빠른지 확인하시기 바랍니다.
PS 답변을 게시한 이후에 파일 형식이 변경된 것을 방금 확인했습니다. 처음에는 값과 file2
값을 테스트하려고 합니다. 두번째열 file1
. 이제 테스트하려는 것 같습니다.첫 번째열 file1
. 이 변경 사항을 수용하려면 $2
위 답변 중 하나와 비교한 섹션을 i
사용하도록 변경해야 합니다 $1
. 또는 전체 행을 테스트하려면 를 file1
사용하십시오 $0
.
따라서 결론적으로 다음을 사용하고 싶을 수도 있습니다.
awk -F, 'FILE != 2 { neg[$1]; next } { ok=1; for (i in neg) if (index($1,i) > 0) ok=0; if (ok) print }' file2 FILE=2 file1
당신의 명령대로. 가독성을 위해 줄 바꿈은 다음과 같습니다.
awk -F, 'FILE != 2 { neg[$1]; next }
{
ok=1
for (i in neg)
if (index($1,i) > 0) ok=0
if (ok) print
}' \
file2 FILE=2 file1