bash와 쉘 프로그래밍은 나에게 새로운 것입니다. 확장자를 가진 파일이 몇 개 있습니다..v.gz, bash 명령에서 일부 작업을 수행하고 결과를 동일한 파일 이름에 저장합니다. . txt확장하다.
예를 들어. txt파일 데이터는 아래와 같습니다. 파일 이름이 다르고 확장자가 동일한 4개의 파일을 고려 중입니다(아마도 30개 이상의 파일이 있을 수도 있음).
file_one.txt
statement_modeule_name_1
statement_modeule_name_2
statement_modeule_name_3
statement_modeule_name_4
statement_modeule_name_5
data.txt 가져오기
statement_modeule_name_6
statement_modeule_name_7
statement_modeule_name_2
statement_modeule_name_8
statement_modeule_name_9
파일.txt
statement_modeule_name_10
statement_modeule_name_11
statement_modeule_name_6
statement_modeule_name_4
statement_modeule_name_14
data_new.txt
statement_modeule_name_15
statement_modeule_name_16
statement_modeule_name_11
statement_modeule_name_5
statement_modeule_name_17
명령 프롬프트에 예상되는 코드 출력
file_one and Fetch_Data statement_modeule_name_2
Fetch_Data and one_file statement_modeule_name_6
file_one and Fetch_Data statement_modeule_name_4
file_one and Fetch_Data and file4 statement_modeule_name_5
Fetch_Data and Data_new statement_modeule_name_11
내가하고있는 코드는
for file in *.v.gz;
do
zgrep -A1 "^module" "$file" | sed -n -e 's/^\(module \)*\(.*(.*)\).*$/\2/p' | cut -f1 -d"(" > $(basename "$file" .v.gz).txt
done #the result what I get here I mentioned in the question .txt files with data (example)
누구든지 이 작업을 수행하는 데 도움을 줄 수 있습니까? python 또는 bash 스크립트를 사용할 수 있습니다(bash의 경우 python 확장을 제거해야 함).
- 이제 첫 번째 단계에서 .txt 형식으로 여러 출력 파일을 생성합니다.
- 이제 여러 .txt 파일을 한 줄씩 비교하고 예상 출력과 같이 파일 이름이 있는 파일에 동일한 줄이 있으면 반환하고 싶습니다.
답변1
$ FILES=( $(find -maxdepth 1 -type f -printf "%P\n") )
$ cat ${FILES[@]} |
sort |
uniq -d |
xargs -r -d '\n' -I{} bash -c '
echo $(sed "s/ / and /g" <<<$(grep -xl "{}" '"${FILES[*]}"')), {}'
결과:
file3.txt and file4.txt, modeule_name_11
file1.txt and file2.txt, modeule_name_2
file1.txt and file3.txt, modeule_name_4
file1.txt and file3.txt and file4.txt, modeule_name_5
file2.txt and file3.txt, modeule_name_6
설명하다:
FILES=( $(find -maxdepth 1 -type f -printf "%P\n") )
-$FILES
파일 목록을 보유하는 배열이 됩니다.cat ${FILES[@]}
- 파일의 내용을 인쇄합니다.sort | uniq -d
- 다른 파일에 나타나지 않는 줄을 확인할 필요가 없으므로 중복된 줄(즉, 둘 이상의 파일에 나타나는 줄)만 표시합니다.xargs -r -d '\n' -I{} bash -c '
- 각 라인에 대해 다음 스크립트를 실행합니다. 구분 기호는 새 줄이므로 특수 문자를 지원할 수 있습니다.{}
우리가 찾고 있는 라인으로 대체될 것입니다grep -xl "{}" '"${FILES[*]}"'
-l
- 각 줄에 대해 전체 줄(-x
)과 일치하는 파일( )을 인쇄합니다.sed "s/ / and /g" <<<$(grep ... ))
- 일치하는 파일 사이의 공백을 다음으로 바꿉니다." 그리고".echo $(...), {}
- 일치하는 항목 목록을 인쇄하고 그 뒤에 일치하는 줄({}
)을 표시합니다.
답변2
모든 데이터를 하나의 스트림으로 연결하되 각 행 앞에 파일 이름을 붙입니다. 데이터에 탭 문자가 없다고 가정하면 탭 문자를 파일 이름과 원본 데이터 사이의 구분 기호로 사용할 수 있습니다. 그런 다음 데이터는 탭으로 구분된 두 번째 필드로 그룹화되고 파일 이름은 각 그룹에 대해 쉼표로 구분된 목록으로 축소됩니다.
awk -v OFS='\t' '{ print FILENAME, $0 }' *.txt |
datamash --sort groupby 2 collapse 1
주어진 질문의 데이터 출력(예를 들어 필드의 순서를 바꿀 수 있음 datamash cut 2,1
):
statement_modeule_name_1 file_one.txt
statement_modeule_name_10 onefile.txt
statement_modeule_name_11 Data_New.txt,onefile.txt
statement_modeule_name_14 onefile.txt
statement_modeule_name_15 Data_New.txt
statement_modeule_name_16 Data_New.txt
statement_modeule_name_17 Data_New.txt
statement_modeule_name_2 Fetch_Data.txt,file_one.txt
statement_modeule_name_3 file_one.txt
statement_modeule_name_4 file_one.txt,onefile.txt
statement_modeule_name_5 Data_New.txt,file_one.txt
statement_modeule_name_6 Fetch_Data.txt,onefile.txt
statement_modeule_name_7 Fetch_Data.txt
statement_modeule_name_8 Fetch_Data.txt
statement_modeule_name_9 Fetch_Data.txt
또는 mlr
GNU 대신 Miller( )를 사용하세요 datamash
.
awk -v OFS='\t' '{ print FILENAME, $0 }' *.txt |
mlr --tsv -N nest --ivar , -f 1
질문의 데이터 출력을 제공합니다.
Data_New.txt statement_modeule_name_15
Data_New.txt statement_modeule_name_16
Data_New.txt,onefile.txt statement_modeule_name_11
Data_New.txt,file_one.txt statement_modeule_name_5
Data_New.txt statement_modeule_name_17
Fetch_Data.txt,onefile.txt statement_modeule_name_6
Fetch_Data.txt statement_modeule_name_7
Fetch_Data.txt,file_one.txt statement_modeule_name_2
Fetch_Data.txt statement_modeule_name_8
Fetch_Data.txt statement_modeule_name_9
file_one.txt statement_modeule_name_1
file_one.txt statement_modeule_name_3
file_one.txt,onefile.txt statement_modeule_name_4
onefile.txt statement_modeule_name_10
onefile.txt statement_modeule_name_14
답변3
comm
당신의 친구입니다. 두 파일 모두에 대해:
$ comm -12 <(sort file_one.txt) <(sort Fetch_Data.txt)
statement_modeule_name_2
txt
현재 디렉터리의 모든 파일에 대해:
for FILE1 in *.txt; do
for FILE2 in *.txt; do
[ "$FILE1" == "$FILE2" ] && continue
echo "$FILE1 $FILE2 $(comm -12 <(sort $FILE1) <(sort $FILE2))"
done
done
file1
ps: 이 솔루션은 and 와 file2
나중에 비교하기 때문에 약간 중복됩니다 .file2
file1
데이터를 출력합니다:
Data_New.txt Fetch_Data.txt
Data_New.txt file_one.txt statement_modeule_name_5
Data_New.txt onefile.txt statement_modeule_name_11
Fetch_Data.txt Data_New.txt
Fetch_Data.txt file_one.txt statement_modeule_name_2
Fetch_Data.txt onefile.txt statement_modeule_name_6
file_one.txt Data_New.txt statement_modeule_name_5
file_one.txt Fetch_Data.txt statement_modeule_name_2
file_one.txt onefile.txt statement_modeule_name_4
onefile.txt Data_New.txt statement_modeule_name_11
onefile.txt Fetch_Data.txt statement_modeule_name_6
onefile.txt file_one.txt statement_modeule_name_4
comm
여기에서 또 다른 주제 에 대해 자세히 알아보세요 .두 파일 사이의 공통 줄