
フォルダ内のすべてのファイルを繰り返す必要があるbashスクリプトがあります。
これは私の現在の機能です。
function listDir(){
for file in "$1"/*;
do
echo $file
done
}
問題は、隠しファイルまたはフォルダ(.hiddenFile)が一覧表示されないことです。どうすればいいですか?
Kusalanandaの答えに基づいて、次のようにスクリプトを編集しました。
listDir () {
for file in $(find "$1" -maxdepth 1 -mindepth 1 -print);
do
echo $file
done
}
ただし、名前にスペースが含まれるフォルダーではこの機能は機能しません。ファイル名をリストするだけでなく、ファイル名で別の操作を実行するには for ループが必要です。
この問題をどのように解決できますか?
答え1
デフォルトでは、シェル*
グローブパターンは隠された名前と一致しません。
ではbash
、シェルオプションを有効にしてこれを達成できますdotglob
。あなたはこのようなことをしていますshopt -s dotglob
。
$file
また、コードから拡張を引用する必要があります。それ以外の場合、シェルはその値に対してトークン化とファイル名のグロービングを実行します。
listDir () (
shopt -s dotglob
for pathname in "$1"/*; do
printf '%s\n' "$pathname"
done
)
上記のループで他の操作を実行する必要がある場合は、$pathname
変数拡張を二重引用符で囲む必要があります"$pathname"
。これにより、さまざまな文字を含むファイル名に対して機能が機能します。
この関数を呼び出すときにスペースが含まれている場合は、ディレクトリ名を引用符で囲む必要があります。
listDir "my directory/here somewhere"
2つの選択肢(ファイルをリストするだけでよいと仮定):
listDir () (
shopt -s dotglob
printf '%s\n' "${1:-.}"/*
)
関数本体を(サブシェル)に囲み、呼び出しシェルにシェルオプションが設定されていないことを( ... )
確認してください。dotglob
justの代わりにinを使用して${1:-.}
ディレクトリ(または空の文字列)が指定されていない場合$1
(現在のディレクトリ)を一覧表示するデフォルトディレクトリとして使用します。.
printf
書式文字列のプレースホルダよりも多くの引数が指定された場合、ユーティリティはその書式文字列を再利用します。ここでは、この事実を使用して、ファイル名を改行区切りリストとして印刷します。
を使用してください。find
以下は必要ありませんdotglob
。
listDir () {
find "${1:-.}" -maxdepth 1 -mindepth 1 -print
}
find
使用中に見つかったファイルに対して他のタスクを実行するにはいいえループの出力を試してくださいfind
。代わりに、以下を使用してください-exec
。
listDir () {
find "${1:-.}" -maxdepth 1 -mindepth 1 -exec sh -c '
for pathname do
# code that does something with "$pathname"
done' sh {} +
}
関連:
答え2
bashにタグを付けたので、配列を使用することもできます。
shopt -s dotglob
files=( "$1"/* )
その後、印刷または作業できます。
printf "File: %s\n" "${files[@]}"
または
rm "${files[@]}"
または
for f in "${files[@]}"; do mv "${f}" "renamed-${f}"; done