私はスクリプトを介してファイルとフォルダを整理しようとしています。私のファイルの最初の文字でフォルダを作成し、そこに移動します。
最初はスクリプトが操作を実行しますが、新しいファイルを作成してスクリプトを再実行すると、フォルダ内に新しいサブフォルダが作成される式です。
たとえば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
等を使用します。また、ファイル名を繰り返すスクリプトでは絶対に使用しないでください。tr
bash
ls
なぜ`ls`を解析しないのですか*(そしてどうすればいいですか?)なぜ)。
別の問題は、名前が同じ文字で始まる何千ものファイルがある場合、このコマンドmv "$first"* tmp/
(または2番目のコマンドmv
)が「引数リストが多すぎる」エラーで失敗する可能性があることです(例:lsのパラメータリストが長すぎます。;この質問は)mv
だけでなく、他のすべての外部コマンドにも適用されますls
。
これらの問題を解決するサンプルスクリプトは、bash
Except 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
"--"(二重ダッシュ) とはどういう意味ですか?)。
このスクリプトの主な違いは、あなたのように最初の文字を繰り返すのではなく、ディレクトリの名前を繰り返すことです。