名前にスペースが含まれているファイルを繰り返し、各ファイルの最初の文字で新しいフォルダを作成し、ファイルをそのフォルダに移動します。

名前にスペースが含まれているファイルを繰り返し、各ファイルの最初の文字で新しいフォルダを作成し、ファイルをそのフォルダに移動します。

現在のディレクトリ(名前にスペースを含む)のファイルを繰り返し、ファイルの最初の文字(まだ作成されていない場合)で新しいフォルダを作成し、移動するこのbashスクリプトを実行しようとしています。そのフォルダにファイルを置きます。これは私のコードです。

for i in `/bin/ls | xargs`
do
    dir=`echo "$i" | cut -c 1 -`
    mkdir -m777 -p "$dir"
mv "$i" "$dir"
done

この問題は、ファイル内の各単語を別々のファイルとして扱うため、フォルダを正しく作成してもファイル名を見つけることは、ファイル名だけを見つけるためにファイルをそのフォルダに移動できないことです。実際のファイルの最初の単語。同様の質問に対する他の答えを見てみましたが、これが私が得ることができる最も近い答えです。

編集:/bin/ls | xargs @steeldriverの提案に従って、「for i in」を「for i in *」に変更し、元の問題を解決しましたが、次のエラーが発生しました。

mv: cannot move '`' to a subdirectory of itself, '`/`'
mv: invalid option -- ' '
mv: missing destination file operand after '-'
mv: invalid option -- '.'
mv: invalid option -- ')'
mv: invalid option -- '+'
mv: cannot move ''$'\340' to a subdirectory of itself, ''$'\340''/'$'\340'
mv: cannot move ''$'\303' to a subdirectory of itself, ''$'\303''/'$'\303'
mv: cannot move ''$'\305' to a subdirectory of itself, ''$'\305''/'$'\305'
mv: invalid option -- '1'

一部のファイルはASCII以外の文字で始まるようです(ファイルが多すぎて内容を見ることができません)。このような状況に対処するためのソリューションはありますか?

ベストアンサー1

名前にスペースを含むファイルを繰り返すには、シェルで十分であるため、次を呼び出す必要はありませんls

for    i in *                   # * replaces the complex (and unquoted) `/bin/ls | xargs`
do
       dir=${i%"${i#?}"}        # replaces the slow subshell `echo "$i" | cut -c 1 -`

       echo "$i"                # just to show that an * is enough (and accepts spaces).
done

リストされているすべてのファイル(ディレクトリを含む)を処理するには、ファイル名がファイル(ディレクトリではない)であることを確認し、ディレクトリを作成する前にそのディレクトリが存在しないことを確認する必要があります。

for i in *
do
    if [ -f "$i" ]; then
        dir=${i%"${i#?}"}
        if [ ! -d "$dir" ]; then
            mkdir -m777 -p "$dir"
        fi
        mv "$i" "$dir"
        if [ "$?" -ne 0 ]; then
            echo "An error occurred moving file \"$i\" to dir \"$dir\""
        fi
    fi
done

おすすめ記事