【问题标题】:How to get bash script to check for consecutive capital letters如何让bash脚本检查连续的大写字母
【发布时间】:2023-03-25 03:40:01
【问题描述】:

我有一个包含一堆 JPEG 的文件夹,我想检查它们的文件名是否符合我的文件名标准:(1) 没有空格,(2) 没有下划线,(3) 没有连续的大写字母,(4) 和每个文件名应以“-original.jpg”结尾。我输出任何错误的文件名,然后提示用户是否继续。下面的脚本非常适用于条件 (1)、(2) 和 (4),但我想将条件 (3) 添加为另一个 elseif。

i=0  # Initialize issue counter

# Detect and indicate any filename issues
for file in *.jpg; do
    if [[ $file = *" "* ]] | [[ $file = *"_"* ]]
        then
        echo "Filename issue: " $file
        i=$((i+1))
    elif [[ $file != *"-original.jpg" ]] 
        then
        echo "Filename issue: " $file
        i=$((i+1))
    fi
done

# If condition satisfied, provide indication of no filename issues
if [[ $i == 0 ]]
then
  echo "No filename issues"
fi
echo

# Prompt user if they want to continue with image processing
read -p "Proceed with image processing? (enter 'y' or 'n') " yn
case $yn in
  [Yy]* ) 
    echo 
    echo "PROCEED"
    echo
    break;;
  [Nn]* ) echo; exit;;
   * ) echo "Please answer yes or no. ";;
esac

我能够将条件 (3) 拼凑在一起,它检测到连续的大写字母,但我不知道如何让它输出它正在解析的更大的字符串 ($name) 和/或将变量传递回较大的 shell 脚本。最好的方法是什么?

echo "$name" | 
awk '{
   for (i=2; i<=NF; i++) {
      if ($i ~ /[A-Z]/ && $(i+1) ~ /[A-Z]/) {
         echo "capitalization problem"
      }
      echo "no capitalization problem"
   }
}' 

【问题讨论】:

    标签: string bash awk


    【解决方案1】:

    使用 bash 提供的正则表达式模式匹配,使用 =~ 内的 [[ ]]

    if [[ $name =~ [[:upper:]]{2} ]]; then
      printf 'Capitalize problem!\n'
    else
      prinf 'No capitalize problem.\n'
    fi
    

    如@shawn所说,更新为[[:upper:]]{2}

    【讨论】:

    • 对于“没有连续的大写字母”,那不就是[[:upper:]]+吗? (或 [[:upper:]][[:upper:]] 使用 BRE)
    • @DavidC.Rankin,感谢您的精彩评论。更新了答案。
    • [[:upper:]]+ 将匹配任何单个大写字母。 [[:upper:]]{2} 连续两个大写字母。
    【解决方案2】:

    您可以使用简单的grep 管道来检查相关的大写字符,例如

    pax:/> if echo aBbd | grep '[A-Z][A-Z]' >/dev/null ; then echo bad ; fi
    pax:/> if echo aBBd | grep '[A-Z][A-Z]' >/dev/null ; then echo bad ; fi
    bad
    

    只需将回显的固定字符串替换为您的实际文件名即可。

    【讨论】:

      【解决方案3】:

      您可以使用*[[:upper:]][[:upper:]]* glob:

      $ cd "$(mktemp --directory)"
      $ touch {a,A}{b,B}{c,C}.jpg
      $ ls
      abc.jpg  abC.jpg  aBc.jpg  aBC.jpg  Abc.jpg  AbC.jpg  ABc.jpg  ABC.jpg
      $ ls *[[:upper:]][[:upper:]]*
      aBC.jpg  ABc.jpg  ABC.jpg
      

      这将比遍历整个文件列表并单独检查它们的模式要快得多。

      【讨论】:

        【解决方案4】:

        您可以将其中一些测试组合在一起:

        for file in *.jpg; do
            if [[ $file =~ [[:space:]_]|[[:upper:]]{2} ]] || [[ $file != *-original.jpg ]]
                then
                echo "Filename issue: $file"
                i=$((i+1))
            fi
        done
        

        首先使用正则表达式查找空格、下划线或两个连续的大写字母,然后使用通配符模式查看文件是否以-original.jpg 结尾。如果任一测试成功,则文件名无效。如果两者都失败了,那很好。

        【讨论】:

          【解决方案5】:

          为了简单有效地测试 (1) 没有空格,(2) 没有下划线,(3) 没有连续的大写字母,(4) 并且每个文件名都应该使用任何 POSIX awk 以“-original.jpg”结尾外壳:

          awk '
          BEGIN {
              if ( ARGV[1] == "*.jpg" ) {
                  exit
              }
              for (i=1; i<ARGC; i++) {
                  fname = ARGV[i]
                  if ( (fname ~ /[[:space:]_]|[[:upper:]]{2}/) || (fname !~ /-original\.jpg$/) ) {
                      gotBad = 1
                      print "Filename issue:", fname | "cat>&2"
                  }
              }
          }
          END {
              if ( ! gotBad ) {
                  print "No filename issues" | "cat>&2"
              }
              exit gotBad
          }
          ' *.jpg
          

          【讨论】:

            猜你喜欢
            • 2017-03-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-28
            • 2013-05-09
            • 1970-01-01
            • 1970-01-01
            • 2021-03-09
            相关资源
            最近更新 更多