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
특별한 상황을 피하기 위해.