bash脚本中表达式中的语法错误
我有以下bash脚本:bash脚本中表达式中的语法错误,bash,Bash,我有以下bash脚本: files=[ls .] for file in $files do digits=$(echo $file | sed "s/[^0-9]*\([0-9]\+\).*/\1/p") if [[ $digits -gt 1000 ]] then rm $file fi done 为什么我会得到: 11923: syntax error in expression (error token is "11923"
files=[ls .]
for file in $files
do
digits=$(echo $file | sed "s/[^0-9]*\([0-9]\+\).*/\1/p")
if [[ $digits -gt 1000 ]]
then
rm $file
fi
done
为什么我会得到:
11923: syntax error in expression (error token is "11923")
其中,11923是$digits变量具有值11923时的一个打印行的示例
编辑:
我发现了错误。调试程序说$digits的值是重复的(例如“1001 1001”)。不过,我不知道为什么会发生这种情况。调试器的输出:
+ for file in *
++ echo image10961.jpg
++ sed 's/[^0-9]*\([0-9]\+\).*/\1/p'
+ digits='10961
10961'
+ [[ 10961
10961 -gt 1000 ]]
test.sh: line 5: [[: 10961
10961: syntax error in expression (error token is "10961")
眼前的问题是:
files=[ls .]
这应该使用$(…)
来执行命令并捕获其输出
files=$(ls .)
不过,真的,最好是这样。最好去掉$files
并使用*
循环当前目录中的所有文件
for file in *
眼前的问题是:
files=[ls .]
这应该使用$(…)
来执行命令并捕获其输出
files=$(ls .)
不过,真的,最好是这样。最好去掉$files
并使用*
循环当前目录中的所有文件
for file in *
不能使用
ls
填充中所述的文件
最简单的方法是使用globbing ie
for file in ./*
do
# do something with $file
done
您可以将扩展正则表达式与sed一起使用
digits=$(echo "$file" | sed -E "s/[^0-9]*([0-9]+).*/\1/p")
请注意,$file
是双引号
关于错误
11923: syntax error in expression (error token is "11923")
这是因为您在sed
替换后添加了p
标志。
换成
digits=$(echo "$file" | sed -E "s/[^0-9]*([0-9]+).*/\1/")
默认情况下,除非使用-n
选项,否则默认情况下sed
打印内容不能使用ls
填充文件,如中所述
最简单的方法是使用globbing ie
for file in ./*
do
# do something with $file
done
您可以将扩展正则表达式与sed一起使用
digits=$(echo "$file" | sed -E "s/[^0-9]*([0-9]+).*/\1/p")
请注意,$file
是双引号
关于错误
11923: syntax error in expression (error token is "11923")
这是因为您在sed
替换后添加了p
标志。
换成
digits=$(echo "$file" | sed -E "s/[^0-9]*([0-9]+).*/\1/")
默认情况下,sed
默认打印内容,除非您使用-n
选项此处,此脚本应适用于您的情况
#!/bin/bash
for file in ./f*
do
digits=$(echo -n $file | sed -n -e "s/[^0-9]*\([0-9]\+\).*/\1/p")
if [ $digits -gt 1000 ]
then
rm $file
fi
done
解析ls
中返回的结果是一件棘手的事情,另一个答案中提到了这一点。以下是我为了让它工作而做的一些改变
首先,echo-n
,它不会打印额外的新行字符。
然后sed-n
,sed的静默模式将不会打印不匹配的行
最后,更重要的是,[
的语法与[
不同。如果您想使用-gt
,您需要使用[
,在这里,这个脚本应该适用于您的情况
#!/bin/bash
for file in ./f*
do
digits=$(echo -n $file | sed -n -e "s/[^0-9]*\([0-9]\+\).*/\1/p")
if [ $digits -gt 1000 ]
then
rm $file
fi
done
在ls
中解析返回的结果是一件棘手的事情,正如另一个答案中提到的
首先,echo-n
,它不会打印额外的新行字符。
然后sed-n
,sed的静默模式将不会打印不匹配的行
最后,更重要的是,[
的语法与[[
不同。如果您想使用-gt
,您需要使用[
您的代码可以简化如下:
for file in *; do
[[ $file =~ ([0-9]+) ]] && (( 10#${BASH_REMATCH[0]} > 1000 )) && rm "$file"
done
它不会为每个文件调用sed
,因此效率更高。如果这还不够,您可以使用更高级的正则表达式。您的代码可以简化如下:
for file in *; do
[[ $file =~ ([0-9]+) ]] && (( 10#${BASH_REMATCH[0]} > 1000 )) && rm "$file"
done
它不会为每个文件调用sed
,因此效率更高。如果这还不够,您可以使用更高级的正则表达式。这可能会有所帮助:确保变量$digits中始终有一个数字。$files
中包含什么?它是一个文件列表吗?在任何情况下,您都应该使用数组,或者更容易地全局化$files确实是一个文件列表,$digits始终是数字。我已检查sed是否返回数字,因为所有文件都具有相同的模式。@AleksandarJovanovic:能否显示如何填充$files
变量?请添加代码。。这可能会有帮助:确保变量$digits中始终有一个数字。什么是con包含在$files
?它是一个文件列表吗?在任何情况下,您都应该使用数组,或者更容易全局化的$files确实是一个文件列表,并且$digits始终是数字。我已经检查过sed是否返回一个数字,因为所有文件都具有相同的模式。@AleksandarJovanovic:您能展示一下如何填充$filesvariable?请添加代码。错误仍然存在。如果我排除If子句,只回显$digits somwehere,一切正常。这意味着数字提取得很好,尽管我肯定没有使用最佳实践(对此表示抱歉)。错误仍然存在。如果我排除If子句,只回显$digits somwehere,一切正常。这意味着数字提取得很好,尽管我肯定没有使用最佳做法(对此表示抱歉)。无需使用echo-n
抑制换行符。与sed-n
相同:这是一个单独的文件名,因此不需要使用p
和-n
。“如果要使用-gt
,则需要使用[/code>”不正确。[[
支持-gt
。不需要使用echo-n
抑制换行符。与sed-n
相同:这是一个单一的文件名,因此不需要使用p
和-n
。“如果要使用-gt
,则需要使用[
”不正确。[/code>支持-gt>。