フォルダをループしてファイルを一覧表示する

フォルダをループしてファイルを一覧表示する

「sample」という名前のフォルダがあり、その中に 3 つのファイルがあります。sample フォルダ内のこれらのファイルを読み取り、curl を使用して HTTP サイトに投稿するシェル スクリプトを作成したいと考えています。

フォルダー内のファイルを一覧表示するには、次のように記述します。

for dir in sample/*; do
        echo $dir;
        done

しかし、次のような出力が得られます。

sample/log

sample/clk

sample/demo

親フォルダが添付されています。出力は次のようになります(親フォルダ名なし)

log

clk

demo

どうすればいいですか?

答え1

basenameファイルの先頭のパスを削除するために使用します:

for file in sample/*; do
    echo "$(basename "$file")"
done

しかし、なぜそうしないのでしょうか:

( cd sample; ls )

答え2

シェルがサポートしている場合は、パラメータ拡張を使用できます。

for path in sample/*; do
    printf -- '%s\n' "${path##*/}"
done

または、そのディレクトリに移動して、そこでリストを作成することもできます

答え3

ディレクトリで何をしたいかによって異なります。

ディレクトリであるかどうかをチェックせずに単に名前を印刷するには、ls を使用できます。

ls -1 sample

フィルターを使用できるため、find の方が適しています。

find sample -type d -maxdepth 1 -printf '%f\n'

ファイルに対してコマンドを実行する場合は、for ループではなく find を使用する必要があります。

find sample -type d -maxdepth 1 -exec basename {} \;

答え4

*nix システムでは、ほぼすべての文字をファイル名に使用できるため (空白、改行、カンマ、パイプ記号などを含む)、シェル スクリプトで "ls" コマンドの出力を解析しないでください。信頼性がありません。lsの出力を解析すべきでない理由

「find」を使用してファイルのリストを作成します。Bash を使用している場合は、「find」の出力を配列に挿入できます。以下に例を示しますが、動作しない「curl」コマンドを使用していることに注意してください。

searchDir="sample/"
oldFiles=()
while IFS= read -r -d $'\0' foundFile; do
    oldFiles+=("$foundFile")
done < <(find "$searchDir" -maxdepth 1 -type f -print0 2> /dev/null)

if [[ ${#oldFiles[@]} -ne 0 ]]; then
    for file in "${oldFiles[@]}"; do
        curl -F ‘data=@"$file"’ UPLOAD_ADDRESS
    done
fi

関連情報