以下のコードで各ファイルを繰り返しながら、ファイル名が小文字と特殊文字と一致していることを確認し、20文字未満であることを確認しますが、明らかに私のif句が機能しないようです。誰でもアドバイスできますか?
#/bin/bash
Count=$(find . -type f | wc -l)
echo $Count
if [[ ( $Count -ge 2 ) && ( $count -lt 1000 ) ]]
then
for file in *;
do
if [[ $file == [a-z0-9._-] && ${#file} -le 20 ]];
echo "inside if $file ${#file}"
then
[ -f "$file" ] || continue
#Check the extension of the file
ext="${file##*.}"
#check if the file name is ending with .txt push to text directory
if [ $ext == "txt" ]
then
mkdir -p text
mv $file text
fi
#if bash scripts are there push to scripts directory
if [ $ext == "sh" ]
then
mkdir -p Scripts
mv $file Scripts
fi
#if log scripts are there push to log directory
if [ $ext == "log" ]
then
mkdir -p logs
mv $file logs
fi
#if music files are there push to music directory
if [[ $ext == "mp3" || $ext == "flac" ]]
then
mkdir -p Music
mv $file Music
fi
fi
done
fi
答え1
これにはいくつかのマイナーな構文問題があります(ほとんどはshellcheck.netそれを指摘します - おすすめです! )、しかし最大の質問から始めましょう。
if [[ $file == [a-z0-9._-] && ${#file} -le 20 ]];
echo "inside if $file ${#file}"
then
...
ここで最初の問題はglobパターンの[a-z0-9._-]
一致です。単一文字。ファイル名が 1 文字より長い場合、一致するものはありません。ファイル名にそのセットの文字のみを含めるには、代わりに正規表現テストを使用します。 (globパターンマッチングは$file =~ ^[a-z0-9._-]+$
式内[[ ]]
で=
行われ、正規表現マッチングは行われます。)長さチェックをここに置くこともできます(「前のものの1から20の間」を意味します)。==
=~
$file =~ ^[a-z0-9._-]{1,20}$
{1,20}
if
2番目の問題は、その間に複数のコマンドがある場合、then
その状態は次のとおりです。最後のもの式が真か偽と見なされるかを決定します。コマンドはecho
ほぼ常に成功するため、式はtrueで、then
句はほぼ常に実行されます。echo
別の場所に移動するか、完全に削除することをお勧めします。
今小さな質問があります。 shebang(最初の行)では#!
なくで始まる必要があります#
。Count
そしてcount
他の変数です(場合は重要です!)。テストでは、奇妙な解析を避けるために[ ]
変数を二重引用符で囲む必要があります。==
これは非標準であるため、代わりに使用してください[ "$ext" = "txt" ]
。[ $ext == "txt" ]
echo "$Count"
mv "$file" text
if
最後に、拡張を抽出する部分を単一のステートメントに置き換えてから、それに基づいて一連のステートメントを使用したいと思いますcase
(これはほとんどcase
意図された目的です)。
case "$file" in
*.txt )
mkdir -p text
mv "$file" text ;;
*.sh )
mkdir -p Scripts
mv "$file" Scripts ;;
*.log )
mkdir -p logs
mv "$file" logs ;;
*.mp3 | *.flac )
mkdir -p Music
mv "$file" Music ;;
esac