少し輸出しました。マイクロソフトワード文書をプレーンテキストに変換し、この関数を使用して.txt
現在のディレクトリにあるファイルの内容を解析します。
mo1 () {
for i in *.txt; do
echo "File: $i"
grep -n -HC 1 "$@" "$i"
done
}
検索するパターンが複数ある場合は、これを行うことができますmo1 | grep pattern2
。しかし、grep -E 'pattern1.*pattern2[.*...]...'
実行時に関数に提供されるパターンの数(など)によって結果が異なるタスクを実行するにはmo1 pattern1 pattern2 [...]
どうすればよいですか。配列が項目数を提供できることがわかり、@
ループ(finalpattern = '$ 1. * $ 2. * $ 3')を介して変数を設定できます。これは最終的に使用される式になりますgrep
。しかし、関数で式を作成する部分を抽象化する方法がわかりませんか?それとも、このようなことを行うより良いより簡単な方法はありますか?
答え1
printf
内蔵機能を活用できます。
mo1 () {
for file in *.txt; do
grep -n -C1 "$(printf "%s.*" "$@")" "$file"
done
}
この単純なバージョンは.*
最後の要素の後に挿入されます。この特定のユースケースでは重要ではありませんが、他の場合(たとえばgrep -o
。.*
mo1 () {
pattern=$(printf "%s.*" "$@")
pattern=${pattern%??}
for file in *.txt; do
grep -n -C1 "$pattern" "$file"
done
}
Bashでは、printf
出力を変数に直接置くことができますが、これはコマンド置換を使用するよりも少し高速です(ただし、サブシェルが遅いCygwinでも問題ではありません)。
mo1 () {
printf -v pattern "%s.*" "$@"
pattern=${pattern%??}
for file in *.txt; do
grep -n -C1 "$pattern" "$file"
done
}
位置パラメータ間に単一の文字を挿入するには、IFS
その文字を設定してを使用します"$@"
。ただし、この方法は区切り文字が2文字以上の場合は機能しません。 ksh、bashではパターンに現れない文字がある場合、それを利用して結合した後に置換を行うことができます。たとえば、ここではパターンに改行文字を含めることは意味がありません。
mo1 () {
typeset IFS=$'\n'
typeset pattern="$*"
pattern=${pattern//$'\n'/.*}
for file in *.txt; do
grep -n -C1 "$pattern" "$file"
done
}
zshにはもちろん直接的な方法があります。
mo1 () {
for file in *.txt; do
grep -n -C1 ${(j:.*:)@} $file
done
}
答え2
または、--file
grepオプションを使用できます。
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty file contains
zero patterns, and therefore matches nothing. (-f is specified by POSIX.)