File1과 File2를 비교하여 File2에서 일치하는 패턴을 주석 처리합니다.

File1과 File2를 비교하여 File2에서 일치하는 패턴을 주석 처리합니다.

테스트 이름이 포함된 목록 파일이 2개 있습니다. 한 파일에는 기본 테스트 이름이 포함되어 있습니다(예: ). usb30_tb_7_10다른 파일에는 'include "usb30_tb_7_10.sv".I want to get all names(모든 이름을 가져오고 싶습니다)목록`이는 기본 이름(또는 .sv 제외)이며 다음에서 찾습니다.목록 2전체 줄을 주석 처리합니다.

즉:

목록 1

test1
test3

댓글을 달기 전 목록 2

'include "test1.sv"
'include "test2.sv"
'include "test3.sv"
'include "test4.sv"

비교 후 목록 2

//'include "test1.sv"
'include "test2.sv"
//'include "test3.sv"
'include "test4.sv"

저는 grep/sed/awk를 처음 사용하는데 아직 해결책을 찾지 못했습니다.

awk가 특정 패턴을 입력으로 사용하는 것과 관련된 답변을 보았지만 그다지 도움이 되지 않았습니다.

나는 다음을 시도합니다 :

awk '-include list1.lst {print "// " $0; next} 1' list2.sv

하지만 작동하지 않습니다(오타로 인해 명령이 허용되는 경우에도 마찬가지입니다).

답변1

awk를 사용하세요:

$ awk -F'[".]' 'NR==FNR{a[$0]; next} $2 in a{$0="//"$0} 1' list1 list2
//'include "test1.sv"
'include "test2.sv"
//'include "test3.sv"
'include "test4.sv"

작동 방식:

  • -F'[".]'

    "이는 awk에게 or 발생 시 필드를 구분하도록 지시합니다 ..

  • NR==FNR{a[$0]; next}

    첫 번째 파일을 읽을 때 이는 awk에게 list연관 배열의 a현재 행과 동일한 키를 생성한 다음 나머지 명령을 건너뛰고 해당 next행으로 점프하도록 지시합니다.

    자세한 내용: NRawk가 지금까지 읽은 총 줄 수입니다. FNR현재 파일에서 지금까지 읽은 줄 수입니다. 이 시점에서 FNR==NR우리는 첫 번째 파일을 읽고 있습니다.

  • $2 in a{$0="//"$0}

    두 번째 파일을 읽을 때 이는 현재 줄의 두 번째 필드가 연관 배열의 키인 경우 //줄의 시작 부분에 추가하도록 awk에 지시합니다 a.

  • 1

    이것은 print-the-line에 대한 awk의 신비한 속기입니다.

확장된 예

주석에 언급된 추가 줄을 사용하십시오.

$ cat list1
test1
test3
usb30_suspend_resume
$ cat list2
'include "test1.sv"
'include "test2.sv"
'include "test3.sv"
'include "usb30_suspend_resume.sv"
'include "test4.sv"
$ awk -F'[".]' 'NR==FNR{a[$0]; next} $2 in a{$0="//"$0} 1' list1 list2
//'include "test1.sv"
'include "test2.sv"
//'include "test3.sv"
//'include "usb30_suspend_resume.sv"
'include "test4.sv"

Pastebin 파일 적용

Pastebin의 파일에는 list1에 후행 공백이 있으며 두 파일 모두 Windows 스타일 줄 끝이 있습니다. 이 형식을 처리하려면 다음을 사용하십시오.

awk 'NR==FNR{a[$1]; next} $2 in a{$0="//"$0} 1' FS='[[:space:]]' list1.txt FS='[".]' list2.txt

답변2

솔직히 말해서 지금까지 제공된 스크립트 솔루션을 입력하는 데 걸리는 시간보다 더 짧은 시간에 Vim에서 대화형으로 이 작업을 수행할 것입니다.

vim list2

그런 다음 상단의 list1을 읽으십시오. (list2가 끝나고 list2가 시작되는 위치를 시각적으로 쉽게 확인할 수 있다고 가정하므로 미리 아무것도 표시할 필요는 없지만 :1k a원하는 경우 list2의 원래 행 1을 먼저 표시할 수 있습니다.)

:0r list1

이 명령을 실행하면 커서가 파일 시작 부분의 첫 번째 단어에 놓이게 됩니다 test1.

*커서 아래에 있는 단어의 다음 인스턴스로 이동하려면 이 키를 누르십시오 . (이 줄이 당신이 주석을 달고 싶은 줄이 될 것입니다.)

키를 눌러 삽입 모드로 들어가고(소문자 대신 대문자를 I사용하므로 줄의 공백이 아닌 첫 번째 문자에서 ) 를 입력한 다음 Escape를 누릅니다.I//

n검색어의 다음 인스턴스로 이동하려면 이 키를 누르세요 . ( 문자 다음 줄의 시작 부분에 있으므로 //커서가 방금 찾은 인스턴스로 이동합니다. 따라서 다음 인스턴스로 이동하려면 다시 누르십시오.)

하나의 인스턴스에만 주석을 달면 된다고 가정하면 이제 다시 파일의 시작 부분, 즉 첫 번째 줄에 있게 됩니다. 아래로 이동하려면 키를 누르세요 j. 또는 다음 줄의 공백이 아닌 첫 번째 문자로 이동하려면 Enter 키를 누르세요. 이 경우 결과는 같습니다.

현재 커서가 있는 인스턴스이므로 *다음 인스턴스로 이동하려면 누르세요 .test3

."라인 주석 처리" 작업을 반복하려면 누릅니다 . 포인트 주문은 훌륭합니다. :)

다시 누르세요 n. (두 번.) 예제 텍스트에서는 이제 완료되었습니다. 두 번째 줄인 으로 돌아갑니다 test3. 주석을 달아야 할 줄이 더 있으면 다시 를 입력하세요 j*.nn. 다른 것이 있으면 j*.nn다시 입력하세요.

작업이 완료되면( test3사용 중인 마지막 줄 list1, 원래 첫 번째 줄 바로 위 list2) dgg현재 줄부터 파일의 첫 번째 줄까지 모든 줄을 삭제하여 list1해당 항목이 거기에 나타나지 않도록 합니다. 더 이상.

전체적으로 입력하셨습니다.

vim list2<Enter>

파일을 열고 다음을 수행합니다.

:0r list1<Enter>
*I//<Esc>nn
j*.nn
j*.nn
j*.nn
(Repeat however many times)
dgg

그런 다음 저장하고 종료하려면 다음을 입력 :x하고 Enter를 누르십시오.


편집하다:

귀하의 "list1"이 큰 것으로 알고 있습니다. 그것은 중요하지 않습니다. 단지 매크로를 사용하십시오.

위 작업을 몇 번 수행하여 제대로 작동하는지 확인한 후 다음을 입력하세요.

qkj*.nnq

이는 j*.nn레지스터에 매크로로 기록됩니다 k.

를 입력하여 매크로를 실행합니다 @k.

다시 실행하려면 Enter를 누르세요 @@.

그런 다음 run it 4000 times 을 입력하세요 4000@@. 하지만 개인적으로 저는 작은 부분으로 나누어서 하고 싶습니다. 매크로에서 점 명령을 사용하는 대신 명시적으로 입력할 수도 있습니다 I//<Esc>.

요점은 내가 할게아직대화식으로 수행하면 됩니다.아직처리해야 하는 행 수가 아무리 많아도 1~2분 밖에 걸리지 않습니다. Vim의 마법. :)

답변3

알고리즘은 다음과 같습니다.

 for each line of List2
     if line matches ANY pattern in List1 then
         print //line
     else
         print line

bash(또는 이와 유사한)의 구현은 다음과 같습니다.

 while read line ;do
     if echo $line | fgrep -f List1 >/dev/null ;then
         echo "//$line"
     else
         echo "$line"
     fi
 done < List2

관련 정보