파일에 다른 파일의 내용에 대한 정규식이 포함되어 있는 경우 해당 줄을 제거하세요.

파일에 다른 파일의 내용에 대한 정규식이 포함되어 있는 경우 해당 줄을 제거하세요.

DNS 레코드가 포함된 대용량 파일(150,000줄 이상)이 있는데 FileA라고 부르겠습니다. 일부 이름이 포함된 더 작은 파일 FileB가 있습니다. FileA의 모든 행을 삭제하고 싶습니다.다음으로 끝남FileB에 무엇이 있습니까? 하지만 난 그래아니요이름이 레코드 시작 부분에 나타나면 행을 제거하려고 합니다.

grep -v name$레코드 끝에 나타나는 이름을 수동으로 제거하는 방법을 알고 있지만 전체 FileB를 통과하려면 루프가 필요합니다. 지금까지의 시도는 실패했습니다.

다음은 제가 추구하는 바를 보여주기를 바라는 예입니다.

FileA:
hosta IN A 10.20.30.40
hostb IN A 20.30.40.50
myurl IN CNAME hostb
yours IN CNAME hostb

FileB에 호스트가 포함되어 있으면 마지막 두 줄만 삭제되고 처음 두 줄은 그대로 유지됩니다.

답변1

-f플래그를 사용하여 FileB의 모든 줄을 grep할 수 있습니다.

grep -v -f FileB FileA

그것은 당신이 원하는 것입니다. 하지만 이렇게 하면 패턴이 있는 FileB줄 도 삭제됩니다.아니요끝에만 일치해야 한다고 명시적으로 명시합니다. 따라서 이에 상응하는 수정이 필요합니다 FileB. ,를 사용하여 줄 끝 기호를 sed추가 할 수 있습니다 .regex$

sed 's/$/$/' FileB

이는 아무것도 대체하지 않는 것처럼 보이지만 실제로는 $줄의 각 끝에 하나씩 추가됩니다.

이제 프로세스 대체를 사용하여 이 모든 것을 하나로 묶을 수 있습니다.

grep -v -f <(sed 's/$/$/' FileB) FileA

답변2

전체 FileB를 반복하려면 다음을 사용할 수 있습니다.

for i in `cat FileB`
do
<do your work>
done

하지만 CNAME으로 필터링하는 것이 더 나을 수도 있습니다.

답변3

다음을 수행할 수 있습니다 sed.

sed -n '/^[^ ]*$/{H;d;};G;/ \(.*\)\n.*\n\1/d;P' fileB fileA

이것은 첫 번째 프로세스 fileB입니다. 이 줄에 공백이 없으면 fileB의 호스트 이름이어야 하며 예약된 공간에 추가하고 계속합니다( {H;d;}).

다른 모든 줄은 fileA에서 가져와야 합니다. G호스트 이름 목록에서 중복된 줄의 마지막 단어가 있는 모든 줄은 호스트 이름 목록( ) 뒤에 예약된 공백을 추가하여 제거할 수 있습니다. 후행 목록( P) 없이 나머지 줄을 인쇄합니다 . 옵션은 -n기본 출력을 비활성화합니다.

편집하다: 사실 사람이 해야 할 일은

sed -n '/^[^ ]*$/{H;d;};G;/ \(.*\)\n.*\n\1\n/d;/ \(.*\)\n.*\n\1$/d;P' fileB fileA

특별한 상황을 피하기 위해.

관련 정보