私はこれをしたい:readarray var1 < <(find "/path/to/dir" \( $var2 \) | sort)
echo $var2
user@domain:~# -name "*.avi" -o -name "*.mkv"
残念ながら私のスクリプトは機能しません。どこで間違っているのか教えてください。
答え1
配列を使用して下さい:
var2=( -name "*.avi" -o -name "*.mkv" )
readarray var1 < <(find "/path/to/dir" \( "${var2[@]}" \) | sort)
関連内容を見てください。変数に保存されたコマンドをどのように実行できますか?
答え2
パスの下のすべての名前を/path/to/dir
ソートされたリストにインポートするには、次のようにしますbash
。
shopt -s globstar nullglob dotglob
names=( /path/to/dir/** )
globstar
のシェルオプションはパス名のように動作しますが、パス名内で一致するglobbash
の使用を許可します(つまり、サブディレクトリで「再帰的に」一致する)。 shellオプションを使用すると、shell globが実行する場合**
*
/
nullglob
いいえ任意の名前と一致すると完全に削除されます(デフォルトはパターンを拡張せずに残すことです)。このdotglob
オプションを使用すると、デフォルトで隠されたファイル名が一致します。
sort
シェル glob の結果拡張は の基本出力と同様にアルファベット順にソートされるため、名前をパイプする必要はありません。sort
.avi
.mkv
ファイル名サフィックスを使用して名前を取得するには
shopt -s globstar nullglob dotglob extglob
names=( /path/to/dir/**/*.@(avi|mkv) )
extglob
ここに拡張されたグローブパターンを使用できるシェルオプションを追加しました。パターンは@(avi|mkv)
「またはavi
」を意味するので、mkv
パターン全体は/path/to/dir
orで終わる以下のすべての名前と一致します。結果の配列がソートされます。.avi
.mkv
find
これは、見つかった名前で操作を実行する必要がある場合、または特定のファイル形式テストを統合する必要がある場合に便利です。たとえば、一致するもののみを確認する必要がある場合一般ファイル、使用
find /path/to/dir -type f \( -name '*.avi' -o -name '*.mkv' \)
2つのファイル名のサフィックスavi
とmkv
配列名が与えられたら、suffix
テスト-name
を配列に整理できます。
suffix=( avi mkv )
nametest=( -false ) # assumes GNU find here
for suf in "${suffix[@]}"; do
nametest+=( -o -name ".$suf" )
done
find /path/to/dir -type f \( "${nametest[@]}" \)
貯蓄はほとんど正確ではありません出力本当に欲しいときはfind
変数に働く名前を見つけようとしています。代わりに、以下を使用してください-exec
。
find /path/to/dir -type f \( "${nametest[@]}" \) -exec sh -c '
for pathname do
# do something with "$pathname" here
done' sh {} +
詳細については、次を参照してください。
- 「find」の-execオプションについて
- 検索結果を繰り返すのはなぜ悪い習慣ですか?
- その他多くの質問と回答探すこのウェブサイトから。