拡張子を持つすべてのファイルを見つけようとします。.md
find . -type f -name "*.md"
次に、2行目(行番号= 2)で、次から始めて終わる正確な文字列を含まないファイルをフィルタリングしたいと思います。author: Mr. Xab Ycd
2番目の部分はどうすればいいですか?grep
ファイル全体をスキャンするため、非効率的です。
答え1
find . -type f -name '*.md' -exec \
sh -c 'sed 1d\;q "$1" | grep -qvx "author: Mr. Xab Ycd"' sh {} \; -print
上記のコマンドには、シェルを介して混乱を招く可能性があるファイル名をパイプする必要なく、すべての要件が含まれています。
最初の部分は(ほぼ)あなたのものからコピーされました。というファイルを探します*.md
。あなたの場合は、二重引用符を「ハード」一重引用符に変更しましたが、名前付きファイルを見つけるには*.$md
二重引用符を使用してください。 、変数を拡張しようとします$md
。
一致するファイル名は別のテストに合格します-exec
。 execの引数は、.txtにある特定のファイル名の成功または失敗を決定する小さなシェルスクリプトです$1
。このsed
コマンドは、2 行目だけを印刷します。これを行う方法はさまざまです。たとえば、次のようになります。
sed -n '2{p;q;}'
またはsed '1d;q
1つ目は、「デフォルトでは行は印刷されませんが、2行目が表示されたら印刷してから終了します」と言います。 2番目は、「デフォルトでは行を印刷しますが、最初の行を削除してから(2行目で)終了することを意味します。このq
コマンドは、終了する前に現在のバッファを印刷します。
テキスト行(存在する場合)はgrepに渡され、行全体が指定されたテキストと一致する(または一致しない)ことを確認します。もしそうならいいえ一致(-v
)すると、コマンド全体が成功し、find
ファイル名が印刷されます。
答え2
find . -type f -name '*.md' -exec awk '
FNR == 2 && $0 == "author: Mr. Xab Ycd" { exit 1 }
FNR > 2 { exit 0 }' {} ';' -print
これは、少なくとも2行の長さのファイルをフィルタリングするために使用され、2行目awk
は正確に言及された文字列です。 2行目(FNR == 2
)が文字列とまったく同じ場合は、ゼロ以外の終了状態で明示的に終了してこれを行います。 2行目以降の行に達すると、不要なコンテンツの解析を避けるために終了ステータス0で終了します。
終了ステータスが0の場合(2行目に文字列が見つかりません)、コマンドはfind
ファイルのパス名を印刷し続けます。-print
awk
答え3
そしてzsh
:
by_Xab() {
local line
{
IFS= read -r line &&
IFS= read -r line &&
[[ $line = "author: Mr. Xab Ycd" ]]
} < ${1-$REPLY}
}
printf '%s\n' **/*.md(D.^+by_Xab)
ファイルごとに最大2行を読み取ってコマンドを実行しない(すべて組み込みコマンド)、ファイルごとに1find -exec
つ以上のコマンドを実行するよりもはるかに効率的です。
GNUを使用すると、awk
次のことができます。
STRING='author: Mr. Xab Ycd' find . -name '*.md' -type f -exec gawk '
BEGINFILE {found = 0}
FNR == 2 {found = $0 == ENVIRON["STRING"]; nextfile}
ENDFILE {if (!found) print FILENAME}' {} +
単一の呼び出しを実行しfind
、できるだけ少ない-exec ... {} +
呼び出し構文を使用します。gawk
答え4
一度に1つのファイルを提供して印刷するときのfind
責任は次のとおりですfind
。
find . -type f -exec perl -lne '$. == 2 && exit +/^author: Mr\. Xab Ycd$/' {} \; -print
これにはfind
複数のファイルがあり、印刷ジョブは次のコマンドで処理されますperl
。
find . -type f -size 0 -print -o -exec perl -lne '
print $ARGV if $. == 2 && !/^author: Mr\. Xab Ycd$/;
close(ARGV),next if $. == 2;
print($ARGV),close(ARGV) if eof;
' {} +
これ閉鎖-イギリス閉鎖ARRGV必須OTWラインカウンター、別名$。スケジュールされたファイルに対して初期化されていません。
eof 句が必要で、長さが 1 より大きいファイルの場合、2 行目に到達または確認されません。