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"

我有以下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")
其中,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>。