シェルスクリプトで特定のファイル名を繰り返す場合は、すべてのサブディレクトリで "Example"文字列で始まるすべてのMKVファイルなど、シェルワイルドカードを介してそのファイル名を取得できます。 make it doneを使わずにこれを行うにはどうすればよいですかeval
?
たとえば、次のスクリプトがループを実行すると
#!/usr/local/bin/zsh
for i in /media/mybook/Example*/; do;
t="ls \"$i\"*.mkv"
s=$(eval $t)
echo $s
done
それを削除する方法はありますかeval
?
答え1
なぜ使用するのか気になりますeval
。自分で作成してくださいs=$(ls "$i"*.mkv)
。しかし、呼び出しはls
意味がなく、ファイル名が破損しています。。ファイルを正常に繰り返します。
for dir in /media/mybook/Example*/; do;
if ! [ -d "$dir" ]; then continue; fi
for file in "$dir"/*.mkv; do
if ! [ -e "$file" ]; then continue; fi
echo "$file"
done
done
"$dir"
ディレクトリ名の特殊文字(スペースなど)がそのままになるように二重引用符内にありますが、引用符の*
外側にはワイルドカードとして扱われることに注意してください。
行は、continue
ワイルドカードの不一致の特別なケースをスキップすることです。 shでは、ワイルドカードが一致しない場合はそのままになり、1つの要素がリテラルである名前のリストがfor
表示されます/media/mybook/Example*/
(外部ループの場合)。一部のシェル(ksh、bash、zsh)にはこれを防ぐ方法があります(例:bash)。
shopt -s nullglob
for dir in /media/mybook/Example*/; do;
for file in "$dir"/*.mkv; do
echo "$file"
done
done
ファイルのみを処理し、ディレクトリに対して何もする必要がない場合は、2つのネストされたループを使用する必要はありません。
for dir in /media/mybook/Example*/*.mkv; do
if ! [ -e "$file" ]; then continue; fi
echo "$file"
done
これらすべてのフラグメントは、Example*
サブディレクトリ内のファイルではなく、ディレクトリ自体内のファイルで機能します。ディレクトリを再帰的に移動するには、次を参照してください。コサロナンダの答え。
答え2
使用find
:
find /media/mybook/Example*/ -type f -name '*.mkv' -print
サブディレクトリに再帰的に移動したくない場合は、-maxdepth 1
前に追加してください。-type f
または、ストレートシェルループ(何千ものファイルがある場合は機能しません)を使用し、最初のサブディレクトリレベルのみを表示したいとします。
for pathname in /media/mybook/Example*/*.mkv; do
printf '%s\n' "$pathname"
done
サブディレクトリに再帰するには、または対応するzsh
シェルbash
オプションglobstar
セットを使用します(やはり数千のファイルには適していません)。
for pathname in /media/mybook/Example*/**/*.mkv; do
printf '%s\n' "$pathname"
done
関連:
到着するパス名があるもの:
そしてfind
:
find /media/mybook/Example*/ -type f -name '*.mkv' -exec sh -c '
for pathname do
# Use "$pathname" here
done' sh {} +
...sh -c
明らかに変更される可能性がある場合、またはbash -c
これらのzsh -c
シェルの特別な機能を使用する必要がある場合。
関連:
シェルループを使用してください:
for pathname in /media/mybook/Example*/*.mkv; do
# Use "$pathname" here
done
また関連: