Bash版本4.4.20
Ubuntu 16.04
我需要比较我拥有的特定项目的时间和扩展名。以下是与我尝试执行的操作类似的操作,但错误相同。我不确定错误在哪里,因为shellcheck没有产生错误。
job
错误:
#!/bin/bash
#
while read -r filename; do
extension="${filename##*.}"
if [ "$extension" == "zip" ] && [ "$filename" == "one.zip" ]; then
echo "Filename is $filename"
elif [ "$extension" == "zip" ] && [ "$filename" == "file_1.zip" ] -o [ "$filename" == "file_2.zip" ] -o [ "$filename" == "file_3.zip" ]; then
echo "Filename is $filename"
elif [ "$extension" == "csv" ] && [ "$filename" == "two.csv" ]; then
echo "Filename is $filename"
else
echo "Filename is $filename"
fi
done<fileList.txt
答案 0 :(得分:3)
使用模式匹配来发挥自己的优势:
while IFS= read -r filename; do
if [[ "$filename" = one.zip ]; then
echo "Filename is $filename"
elif [[ "$filename" = file_[123].zip ]; then
echo "Filename is $filename"
elif [[ "$filename" = two.csv ]; then
echo "Filename is $filename"
else
echo "Filename is $filename"
fi
done < fileList.txt
case
语句将在任何 POSIX shell中运行,而不仅仅是支持类似bash
的{{1}}命令的shell。
[[ ... ]]
要匹配年份范围(?),可以使用
while IFS= read -r filename; do
case $filename in
one.zip) echo "Filename is $filename" ;;
file_[123].zip) echo "..." ;;
two.csv) echo "..." ;;
*) echo "..." ;;
esac
done
您不能像使用case $value in
200[0-9]|201[0-9]|202[0-1]) echo "Year between 2000 and 2021" ;;
esac
那样简单地执行此操作,因为[[ value = ... ]]
是|
语句语法的一部分,而不是模式中的交替运算符。相反,您将需要多个匹配运算符:
case
答案 1 :(得分:3)
以下是为什么的解释,您将得到此错误,因为您已经获得正确执行操作的正确答案:
请注意,命令[
与test
等效,因此,有效的第8行(还删除了不必要的引号)包含:
elif test "$extension" == zip ] && test "$filename" == file_1.zip ] -o [ "$filename" == file_2.zip ] -o [ "$filename" == file_3.zip ]
从 test 手册页中,我们可以看到结尾的]
是可选的,但是如果存在,它将终止要测试的表达式。
第一个test
,就是
test "$extension" == "zip" ]
在这方面很好,但是第二个以
开始test "$filename" == file_1.zip ] -o [ ...
因此,当解析参数时,test
会遇到一个]
并知道这是参数的终结符,但随后又找到了另一个参数(-o
),但没有找到知道该怎么办。因此,它抱怨说它有太多的论据
答案 2 :(得分:1)
我已经将语法更新为我认为的现代bash惯用语。该脚本现在可以工作了。如果我错过了其他事情,请纠正我:
#!/bin/bash
#
while read -r filename
do
extension="${filename##*.}"
if [[ "$extension" = "zip" && "$filename" = "one.zip" ]]
then
echo "Filename is $filename"
elif [[ "$extension" = "zip" && "$filename" = "file_1.zip" ]] \
|| [[ "$filename" = "file_2.zip" ]] \
|| [[ "$filename" = "file_3.zip" ]]
then
echo "Filename is $filename"
elif [[ "$extension" = "csv" && "$filename" = "two.csv" ]]
then
echo "Filename is $filename"
else
echo "Filename is $filename"
fi
done < fileList.txt
致谢!