ファイルをアルファベット順のフォルダーにソートする Bash スクリプト

ファイルをアルファベット順のフォルダーにソートする Bash スクリプト

私はスクリプトを介してファイルとフォルダを整理しようとしています。私のファイルの最初の文字でフォルダを作成し、そこに移動します。

最初はスクリプトが操作を実行しますが、新しいファイルを作成してスクリプトを再実行すると、フォルダ内に新しいサブフォルダが作成される式です。

たとえばT/T/toto.txt

私のスクリプト:

for first in $(ls -1 | sed 's/^\(.\).*$/\1/' | tr '[a-z0-9]' '[A-Z0-9]' | uniq)
do
    mkdir tmp
    mv "$first"* tmp/
    lower=$(echo $first | tr '[A-Z]' '[a-z]')
    mv "$lower"* tmp/
    mv tmp/ "$first";
done

答え1

スクリプトが実行中です。目次ディレクトリ以外のファイルをソートしたい単一文字ディレクトリであっても、名前に基づいてサブディレクトリに移動します。これが新しいディレクトリが表示される方法です。また、あなたのコードは、シェルがより速くより安全に実行できるようにするために不必要にsed等を使用します。また、ファイル名を繰り返すスクリプトでは絶対に使用しないでください。trbashlsなぜ`ls`を解析しないのですか*(そしてどうすればいいですか?)なぜ)。

別の問題は、名前が同じ文字で始まる何千ものファイルがある場合、このコマンドmv "$first"* tmp/(または2番目のコマンドmv)が「引数リストが多すぎる」エラーで失敗する可能性があることです(例:lsのパラメータリストが長すぎます。;この質問は)mvだけでなく、他のすべての外部コマンドにも適用されますls

これらの問題を解決するサンプルスクリプトは、bashExcept fromおよびmkdirの関数のみを使用しますmv

#!/bin/bash

shopt -s nullglob  # makes the loop not loop at all if there are no files

for name in *; do
    if [[ -d $name ]] && [[ $name == ? ]]; then
        # skip directories that have single character names
        continue
    fi

    # get first character in filename
    first=${name:0:1}

    # compute destination directory name from this first
    # character by uppercasing it
    destdir=${first^}

    # make that directory if it does not already exist
    mkdir -p -- "$destdir"

    # move the file into place (name collisions not checked for)
    mv -- "$name" "$destdir"
done

--オプションを使用し、ダッシュで開始できるファイル名をmkdir防止します(例:mv"--"(二重ダッシュ) とはどういう意味ですか?)。

このスクリプトの主な違いは、あなたのように最初の文字を繰り返すのではなく、ディレクトリの名前を繰り返すことです。

関連情報