我试图在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
答案 0 :(得分: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
请注意,您可以使用多个if
语句块并在最后只有一个else
条件来检查是否符合 N 命名约定,如下所示:
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个命名约定的文件名)< / p>
答案 1 :(得分: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/'