他のtxtファイルのリストから検索したいパターンのリストを含むファイル(search.patterns)があります。
検索モード
home
dog
cat
ファイル1.txt
home 3
tiger 4
lion 1
ファイル2.txt
dolphin 6
jaguar 3
dog 1
ファイル3.txt
donkey 3
cat 4
horse 1
だから、file1でパターンファイルの最初の行、file2から2行目、file3から3行目を検索したいと思います。
出力:
home 3
dog 1
cat 4
私は次のようなコードを書いた。
for f in *.txt;
do
while IFS= read -r LINE;
do grep -f "$LINE" "$f" > "$f.out"
done < search.patterns
done
しかし、出力ファイルは空です。
どんな助けでも大変感謝します。ありがとうございます。
答え1
GNU awk()を使用すると、入力ファイルが変更されるたびにルールをgawk
使用して新しいパターンを読み取ることができます。BEGINFILE
$ gawk 'BEGINFILE{getline pat < "search.patterns"} $0 ~ pat' file\ {1..3}.txt
home 3
dog 1
cat 4
getline
たとえば、新しいモードが返されることを実際に確認する必要があります。
gawk '
BEGINFILE {
if((getline pat < "search.patterns") <= 0) {
print "Error reading pattern" > "/dev/stderr"
exit 1
}
}
$0 ~ pat
' file\ {1..3}.txt
ちなみにawk
パターンは拡大するgrep
with オプション-E
がサポートする式に似た正規表現です。
最初のファイルに渡して適切に使用して、パターンをインデックス配列として読み取るか、配列内の次のパターンを見つけることで、awk
非GNUでも同じ効果を得ることができます。search.patterns
NR
FNR
答え2
使用bash
:
#!/bin/bash
files=( 'file 1.txt' 'file 2.txt' 'file 3.txt' )
while IFS= read -r pattern; do
grep -e "$pattern" "${files[0]}"
files=( "${files[@]:1}" )
done <search.patterns
テストしてみてください:
$ bash script.sh
home 3
dog 1
cat 4
スクリプトは関連ファイル名をfiles
配列に保存し、ファイルsearch.patterns
からパターンを読み取ります。各パターンについて、files
リストの最初のファイルが照会されます。その後、処理されたファイルはリストから削除されますfiles
(結果として、リストの最初の最初のファイル名が生成されます)。
パターン数がのファイル数を超えるとfiles
エラーが発生しますgrep
。
答え3
paste
このパターンを使用してファイルを一致させることができます。
paste <(printf "%s\n" *.txt) search.patterns | while IFS=$'\t' read -r file pattern; do
grep -- "$pattern" "$file"
done
ファイル名にタブ文字が含まれていないとします。