1

我试图在将移动原始相机文件的 Mac 上编写一个 shell 脚本。这些文件需要非常具体地命名。我有正则表达式来检查文件名,我只是没有运气让它正常工作。正常工作是在特定文件夹中查找包含原始文件的文件夹名称并获取文件列表。

我也在尝试错误检查。我一直在尝试使用 if 语句来检查文件名。

我需要帮助编写 if 语句以检查文件是否正确命名。

我将非常感谢任何帮助,因为我完全被困在这一点上。

这是我到目前为止所拥有的:

#!/bin/bash

product="^[A-Z0-9]{2}\w[A-Z0-9]{6,7}\w[A-Z]{1}\.(EIP)"

#folder of files to check
folder_files="$(ls -d *)"

#just get a list of everything .EIP
FILES_LIST="$(ls *.EIP)"

for file in $FILES_LIST; do
#something with $file

echo $file

#where im having the trouble 
If (grep or find based on $product)
then

    #move files, create log

else

    #move files to an error folder for renaming

fi

done
exit 0
4

2 回答 2

2

花括号是扩展正则扩展 (ERE) 语法的一部分,而不是基本正则表达式 (BRE) 语法,因此我们需要使用“egrep”。我还冒昧地从您的正则表达式中删除了括号,因为我看到您正在寻找以结尾的文件,.EIP所以这给我们留下了:

product="^[A-Z0-9]{2}\w[A-Z0-9]{6,7}\w[A-Z]{1}\.EIP"

我们还需要更改$IFS变量,因为 FOR 循环使用它来确定字段分隔符。默认情况下,字段分隔符设置为空格字符,这不适用于字段分隔符可以是字符串一部分的字符串(即,如果文件名包含空格)。我们将 IFS 的当前值存储到一个变量中并设置 IFS:

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

完成后,我们将 IFS 恢复到其原始值:

IFS=$SAVEIFS

现在我们将文件名通过管道传递给 egrep 并使用我们的正则表达式进行过滤,同时将stdout和重定向stderr/dev/null. 该$?变量将让我们知道 egrep 是否返回了匹配项。

echo $file | egrep $product &>/dev/null
if [ $? -eq 0 ]; then 
  echo "$file - acceptable"
else 
  echo "$file - not acceptable"
fi

这是完整脚本的样子(在山狮上测试):

#!/bin/bash 

product="^[A-Z0-9]{2}\w[A-Z0-9]{6,7}\w[A-Z]{1}\.EIP"

FILES_LIST="$(ls *.EIP)"

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

for file in $FILES_LIST; do
  echo $file | egrep $product &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - acceptable"
    #move files, create log
  else 
    echo "$file - not acceptable"
    #move files to an error folder for renaming
  fi
done

IFS=$SAVEIFS

exit 0

请注意,您可以通过使用多个语句块和最后一个条件来检查是否符合N命名约定,如下所示:ifelse

for file in $FILES_LIST; do

  echo $file | egrep $regex1 &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - accepted by regex1"
    #move files, create log
    continue
  fi

  echo $file | egrep $regex2 &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - accepted by regex2"
    #move files, create log
    continue
  fi

  echo $file | egrep $regexN &>/dev/null
  if [ $? -eq 0 ]; then 
    echo "$file - accepted by regexN"
    #move files, create log
  else 
    echo "$file - not acceptable"
    #move files to an error folder for renaming
  fi
done

注意使用,continue因为它恢复了循环的迭代for,允许每个文件只执行一个操作(考虑文件名符合超过 1 个命名约定)

于 2013-08-20T22:46:23.770 回答
1

我不确定macosx是否使用gnu find,但我敢打赌它确实如此。

find . -regextype posix-egrep -ireg ${myregex} -print

要匹配的文件名包括整个路径,因此您需要以 ^./ 开始您的正则表达式并以 $ 结尾

而不是 if,我更愿意将整个事情写成两个 xargs。

# first move the good stuff to its destination
find . -type f -regextype posix-egrep -ireg ${myregex} -print0 | xargs -I{} -0 mv {} ../good-dir/
# anything remaining is bad
find . -type f -print0 | xargs -I{} -0 sh -c 'echo "bad file name: {}" > /var/log/whatever.log; mv {} ../bad-dir/'
于 2013-08-20T21:24:42.930 回答