테스트 이름이 포함된 목록 파일이 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
행으로 점프하도록 지시합니다.자세한 내용:
NR
awk가 지금까지 읽은 총 줄 수입니다.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