私には木があります。
.
├── 1
│ └── a
│ └── script.a.sh
├── 2
│ └── a
│ └── script.b.sh
...
└── a
└── script.sh
私は見つけるべきですscript.*.sh
。私は以下を実行します./a/script.sh
:
#!/bin/bash
#
path="/tmp/test"
readarray files < <(find ${path} -path "*/a/script.*.sh")
if [ ${#files[@]} -ne 0 ]
then
for file in "${files[@]}"
do
echo ${file}
done
fi
出力:
/tmp/test/1/a/script.a.sh
/tmp/test/2/a/script.b.sh
これは有効なスクリプトです!
find ${path} -path "*/a" -name "script.*.sh"
ただし、findコマンドをスクリプトに変更すると、何も出力されません。
私のロジックは/tmp/test/*/a/script.*.sh
私が言うパターンを持つすべてのファイルを探しますfind ${path} -path "*/a" -name "script.*.sh"
。
現在残っている質問は次のとおりです。
find ${path} -path "*/a" -name "script.*.sh"
コマンドは実際に何をしますか?- にデバッグモードがありますか
find
?私の言葉は、私が何を言っているのかを理解する方法を意味します(例:検索するパス、nofind . -name "*te.st*"
、just./*/*te.st*
)。 -name
、同じコマンドライン(必要なケース、はい、説明)にありますか-path
?それとも相互排他的ですか?それとも-path
拡張バージョンと言えますか-name
?
man
はい、はい、およびを使用できますgoogle
。また、これらのソースからすべての質問に対する完全な答えが見つかりませんでした。
答え1
-path
GNUバージョンの引数は、find
開始ディレクトリを含むアクセスされるオブジェクトのフルパスに適用されるパターンを指定します。
パターンはパターンですが、スラッシュは特に扱われません。たとえば、パスとパターンのa/b/c/d
一致ですa*d
。
これはシェルステートメントのパターンcase
マッチングと似ています。
$ case a/b/c/d in a*d ) echo match;; esac
match
パス名拡張でパターンマッチングの代わりに。
$ echo a*d # will not match an a/b/c/d file accessible in this directory!
たとえば、次のようになります。
find /etc -path '*.conf'
一致して印刷されます/etc/foobar/foobar.conf
。パスに出会うと、パスはパターンと一致します。
したがって:
質問:
find ${path} -path "*/a" -name "script.*.sh"
何をしますか?答え:何も見つかりません。
-path
で終わるパスと一致するため、/a
で終わるscript.*.sh
ディレクトリエントリを一致させることはできませんa
。-path
and述語は-name
暗黙の論理ANDにリンクされているため、結果は空です。開始位置はオプションです。省略
find
できます。シェル構文(引用符なしの引数として使用される場合)は、ファイル名拡張子を使用してシェルによって拡張されます。または、一致するものがない場合は、そのままにしておくこともできます。find -name '*.txt'
find . -name '*.txt'
./*/*te.st*
find
-path
Q:ライブと-name
同じコマンドラインにありますか?答え:もちろん可能です。ただし、「and」と組み合わせて競合が発生すると、結果が空になる可能性があります。
find -path X -name Y
意味find -path X -a -name Y -a -print
: アクセスしたパスが一致しないX
場合そしてアクセスされているディレクトリエントリが一致すると、Y
パスが印刷されます。X
一致する名前で終わるY
一致するパスがないと、-print
述語(暗黙的または明示的)に到達できません。何も印刷できません。
答え2
find ${path} -path "*/a" -name "script.*.sh"
ただし、findコマンドをスクリプトに変更すると、何も出力されません。
実際にはそうではありません。述語と一致するファイルは述語-path "*/a"
とも一致できません-name "script.*.sh"
。
私のロジックは
/tmp/test/*/a/script.*.sh
私が言うパターンを持つすべてのファイルを探しますfind ${path} -path "*/a" -name "script.*.sh"
。
あなたが仮定している$path
値は/tmp/test
。この場合、なぜ仕事をそんなに複雑にするのか分かりません。 globを使って目的のパスを正確に説明できるので、find
完全に省略したいと思います。
files=("${path}"/*/a/script.*.sh)
ただし、これを行うには、find
この場合、合計を組み合わせることは意味がありません-name
。-path
すでに観察したように、元のコマンドはこれをfind
行います。そしてもっとシンプルで明確です。
あるいは、部分パスマッチングを元のリストに移動することもできます。
find ${path}/*/a -maxdepth 1 -name "*script.*.sh"
find ${path} -path "*/a" -name "script.*.sh"
コマンドは実際に何をしますか?
${path}
ルートにルートがあるサブツリーで、パス(で始まる${path}
)がパターンと一致し、デフォルト名がパターン*/a
と一致するファイルを検索しますscript.*.sh
。それぞれ完了しました。これら2つの条件を満たすすべてのファイルのパスは印刷されますが、同じファイルが両方の条件を同時に満たすことはできないため、何も印刷されません。
- にデバッグモードがありますか
find
?私の言葉は、私が何を言っているのかを理解する方法を意味します(例:検索するパス、nofind . -name "*te.st*"
、just./*/*te.st*
)。
POSIXにはデバッグツールはありませんが、findutilsとfindutilsの両方がタグfind
付けされているため、GNU findutilsバージョンを使用していることはほぼ確実です。この実装linux
ubuntu
find
するデバッグツールが文書化されています。マンページ。あなたはこのオプションを探しています-D
。どのように役立つかはわかりませんが、最大のデバッグ情報を取得するには、開始点リストの-D all
前にコマンドを追加できます。find
-name
、同じコマンドライン(必要なケース、はい、説明)にありますか-path
?それとも相互排他的ですか?それとも-path
拡張バージョンと言えますか-name
?
はい、一緒に使用することができ、時には組み合わせることが合理的かもしれません。しかし、あなたを混乱させることができるのは
- 彼ら独立と
-path
テストみんなディレクトリ部分だけでなくパス。おそらくあなた-path
がそうしたのかと尋ねたときの状況はそうでした-name
。
-path
述語が実際に選択したいファイルと一致しないため、結合しようとすると失敗します。しかしこれはうまくいきます:
find ${path} -path "*/a/*" -name "script.*.sh"
-o
-a
さらに、暗黙的または明示的(「and」)の代わりに連結詞(「または」を意味)を使用したり、1つまたは2つの述部を否定する組み合わせで使用することができます-not
。