こんにちは。私の作業コマンドは次のとおりです。
grep -l "my text" file*.ext|xargs ls -lart
このコマンドは私にとって非常に効果的です。次のように入力を減らしながら実行できるシェルファイルを作成したいと思います。
fn "my text" file*.ext
このシェルスクリプトファイルが見つかりました。
grep -l "$1" "$2"|xargs ls -lart
最初の部分でも動作しません。
grep -l "$1" "$2"
nullを返す
答え1
スクリプトには3つ以上のパラメータが必要です。
シェルがgrep
コマンドを実行する前に
grep -l "my text" file*.ext
ファイル名ワイルドカードパターンは、file*.ext
一致するすべてのファイル名に拡張されます。したがって、最終的なコマンドラインの実行は次のようになります。
grep -l "my text" file1.ext file2.ext file3.ext
(パターンと一致するファイルの場合)
したがって、スクリプトは次のようになります。
#!/bin/sh
pattern=$1
shift
grep -l -e "$pattern" "$@" | xargs ls -lrt
ここで、パターンは変数に格納されている次のコマンドライン引数のリストから削除されます。残りの引数はファイル名のリストです(コマンドラインのファイル名ワイルドカードパターンが一致する場合)"$@"
。
二重引用符を使用してください$@
。これにより$@
、個別に引用されたコマンドライン引数のリストが展開されます。
リストに明示的なファイル名を指定する場合は不要なので、その-a
オプションを削除しました。また、パターンを指定するためにwithをls
使用します。最初の文字にダッシュ()があるパターンは混乱する可能性があるためです。grep
-e
-
grep
find
ソートでない場合は、パイピングの代わりに以下を使用することをお勧めします(スペースと改行文字を含むファイル名を正しく処理します)。
find . -type f -name "$filepattern" -exec grep -q -e "$pattern" {} ';' -ls
$filepattern
これは、そのコンテンツと一致する名前と、そのコンテンツと一致するコンテンツを持つファイルを検索し、同様の出力を$pattern
生成します。ls -l
検索は現在のディレクトリで繰り返し実行されます。
スクリプトの一部として:
#!/bin/sh
pattern=$1
filepattern=$2
find . -type f -name "$filepattern" -exec grep -q -e "$pattern" {} ';' -ls
これスクリプトは、呼び出されたときにシェルがファイル名のグローブパターンを拡張しないように呼び出す必要があります。
$ ./script.sh 'my text' 'file*.ext'
答え2
より安全にするには、GNU拡張機能を使用してください。
#! /bin/sh -
pattern=${1?pattern required}; shift
: "${1?no filename specified}"
grep -l --null -e "$pattern" -- "$@" |
xargs -r0 ls -lrtd --
--null
/を使用すると、-0
スペース、引用符、またはバックスラッシュを含むファイル名に関する問題を回避できます。
これにより、-e "$pattern"
パターンで始まる問題を回避できます-
。
で--
始まるファイル名の問題を回避できます-
。
を使用すると、-d
ディレクトリタイプのファイルが一致したときに発生する可能性がある混乱を回避できます。
を使用すると、-r
一致するファイルが存在しない場合に現在のディレクトリの一覧を回避できます。
ファイル数が多い場合は、ファイルの一部のリストに対して複数の呼び出しを実行することを選択できますxargs
。つまり、出力が時間ごとに正しく表示されない可能性があります。ls
また、これはstdinがありますが、呼び出されるファイルが-
現在のディレクトリにあることを意味します。grep
GNUはそれを出力します(またはそれをあなたの言語に翻訳します)。現在のディレクトリから呼び出されるファイルを指定するには。-
ls
grep -l
(standard input)
-
./-
-