たくさんのファイルがあるディレクトリにいるとしましょう。ディレクトリ内のすべてのファイルのコンテンツを検索して、「Cheese」ではなく「ER」という文字列を含む最長の行をどのように表示しますか?
これまでのところ、私の知る限り、これを1行のコマンドで実行しようとしています。
ディレクトリ内のすべてのファイルを検索するために、再帰的にgrep -rを使用する必要があると考えていますが、最終的な目標は最長の行を表示することなので、これまでのところ次のようになっていると思います。
grep -r -e "ER"
そして、小さな希望から-v "Cheese"を付けた場合、もちろん動作しません。
これは1行のコマンドでは不可能ですか?もしそうなら、私は複数の行で何をする必要がありますか?
これがawkソリューションです:
awk '/ER/ && !/Cheese/ {if (length($0) > maxlen) { maxline=$0; maxlen=length($0);}} END {print maxlen, maxline;}' *
(また、最も長い行の長さも出力しますが、それが必要ない場合は、... END {print maxline;}
と発声してください。
Jeremy Doverのgrepソリューションに対する利点は、入力を1回通過することです。欠点は、同じ最大長の行が複数ある場合、最初の行(または> =を使用して長さを比較する場合は最後の行)のみが印刷されることです。 grepソリューションはそれらすべてを出力します。
この1行は、(1つのディレクトリ内のファイルに対して)要求したことを実行します。
awk '{l=length($0)}/ER/&&!/Cheese/&&(length($0)>l){l=length($0);line=$0}END{print(line)}' *
一致する行が複数ある場合、これは、チーズではなくERを含み、以前に選択された行よりも長いfirst行のみを出力します。
また、これはpwd(*)内のファイルをスキャンします。再帰が必要な場合は、findコマンドでファイルを選択する必要があります。
find . -type f -iname '*.sh' -exec sh -c 'awk '\''{l=length($0)}/ER/&&!/Cheese/&&(l>lm){lm=l;li=$0}END{print(li)}'\'' "$@"' awksh {} +
または数行で(読みやすくするため):
find . -type f -iname '*.sh' -exec sh -c '\
awk '\''{l=length($0)}/ER/&&!/Cheese/&&(l>lm){lm=l;li=$0}END{print(li)}'\'\
' "$@"' awksh {} +
awk '/ER/ && !/Cheese/ && length > m {
m=length; d=$0; f=substr(FILENAME, 3); n=FNR
}
END { print m, f ":" n, d }' ./*
現在のディレクトリに通常のファイルしかない場合、これにより、質問の条件を満たす最長の行の長さ(m
)と、それが見つかったファイル名(f
)が出力されます。 )、行番号(n
)および行自体(d
)。
出力は次のようになります
8 file:3 Hello ER
最長の行は8文字で、3行目にfile
というファイルで見つかりました。
私は次のワンライナーが機能するはずだと信じています:
L=`grep -h "ER" * | grep -v Cheese | wc -L`; grep -h "ER" * | grep -v Cheese | grep -P ".{$L}"
最初のコマンドは、「ER」を含むディレクトリ内のファイル内のすべての行を検索し(サブディレクトリがある場合は、-R
オプションのみが必要です。それ以外の場合は、glob *
が必要です)、Cheeseを含む行を削除します。 、次にwc -L
コマンドを使用して、これらの行の最も長い行を見つけます。
2番目のコマンド(alas)は、適合行の検索を再度実行しますが、最大長の行を検索します。 grepのバージョンによっては、grepに-P
オプションが必要ない場合があります。
文字列の長さを前に付け、数値でソートし、最初の結果の2番目のフィールドを出力して、元の文字列を元に戻すもの。
grep -h ER * | grep -v Cheese | awk '{ print length($0) " " $0}' | sort -nr| head -1| awk '{print $2}'
このアプローチにより、必要に応じて「MAX」や「MIN」よりも高度なクエリを実行できます。 AWKの使用に注意してください。これはまさにそれが本当に良いことです。