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行ずつ比較し、予想される出力と同じファイル名を持つファイルに同じ行がある場合は返したいと思います。
答え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
すべてのデータを1つのストリームにリンクしますが、各行の前にファイル名を付けます。データにタブ文字がないと仮定すると、タブ文字をファイル名と元のデータの間の区切り文字として使用できます。その後、データはタブ区切りの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
ここで別のトピックの詳細をご覧ください。2つのファイル間の共通行