if 子句不起作用

if 子句不起作用

从下面的代码中,我遍历每个文件并检查我的文件名是否匹配小写和特殊字符,并检查它是否少于 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._-]匹配单个字符。如果文件名长度超过一个字符,则不会匹配。如果您想确保文件名仅包含该集中的字符,请改用正则表达式测试:($file =~ ^[a-z0-9._-]+$请注意,在[[ ]]表达式内部=进行==glob 模式匹配,并=~进行正则表达式匹配)。您还可以将长度检查滚动到此中$file =~ ^[a-z0-9._-]{1,20}${1,20}意思是“前一个事物的 1 到 20 之间”)。

if第二个问题是,当和之间有多个命令时then,它的状态是最后一个确定表达式是否被视为 true 或 false。该echo命令几乎总是成功,因此表达式为真,并且该then子句几乎总是被执行。我建议要么将其移到echo其他地方,要么完全删除它。

现在,对于小问题:shebang(第一行)应该以 开头#!,而不仅仅是#Countcount是不同的变量(大小写很重要!)。在[ ]测试中,您应该用双引号变量来避免奇怪的解析,并且==这是非标准的,因此例如使用[ "$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

相关内容