Bash for 循环中的语法错误
Bash syntax error in for loop
我有一个这样的文件列表"file1.stream_2015-02-17.mp4",我一直在使用这个
删除这些文件
#!/bin/bash
CONTENT_DIR=/my_files/recordings
find $CONTENT_DIR -mtime +1 -regextype posix-extended -regex '.*[.](mp4|tmp)$' -delete
到目前为止,这对我来说一直很好,但现在我想删除所有带有 file1.stream 的 1 天和所有带有 file2.stream 的 7 天
我一直在尝试这个,但我主要是不断出现错误
#!/bin/bash
CONTENT_DIR=/my_files/recordings/*
for f in $CONTENT_DIR; do
if [[ -f ${f} =~ 'file1.stream_*' ]] then
find -mtime +7 ${f} -delete
else
find -mtime +1 ${f} -delete
fi
done
但我一直收到此错误
syntax error in conditional expression
syntax error near `=~'
` if [[ -f ${f} =~ 'file1.stream_*' ]] then'
我不确定错误是什么,我已经四处寻找了几个小时,试图找到语法错误。感谢您的帮助
您的 if
条件中存在语法错误,=~
仅用于正则表达式。
您可以使用:
#!/bin/bash
for f in /my_files/recordings/*; do
if [[ -f "$f" && "$f" == 'file1.stream_'* ]]; then
find "$f" -mtime +7 -delete
else
find "$f" -mtime +1 -delete
fi
done
此外,如我上面的回答所示,glob 模式需要在引号之外。
你似乎在污染两种不同的结构。您需要分别检查它们。
[[ -f "$f" ]]
检查文件 $f
是否存在并且是一个普通文件。
[[ "$f" =~ regex ]]
检查 $f
中的字符串是否匹配正则表达式 regex
.
你可以这样组合它们:
if [[ -f "$f" && "$f" =~ regex ]]; then ...
或者简单地将其分成两个单独的比较:
if [[ -f "$f" ]] && [[ "$f" =~ regex ]]; then ...
另请注意 then
.
之前所需的分号(或换行符)
但是您拥有的模式是 glob 模式,而不是正则表达式,因此您可能想改用 glob 比较。
此外,您的字符串不是 find
的有效参数——我想您的意思是
if ...; then
find -mtime +7 -name "$f" -delete
: etc
或者也许(在这种情况下有点等价)
if ...; then
find "$f" -mtime +7 -delete
: etc
其中参数肯定需要用双引号引起来,否则 shell 将对其执行通配符扩展并用扩展结果替换变量,从而产生另一个语法错误。
最后,将模式放在变量中然后不加引号使用它并不是特别好的形式。该变量似乎没有任何用处,因此只需将模式内联到 for
循环中即可。
for f in /my_files/recordings/*; do
if [[ -f "$f" && "$f" == 'file1.stream_'* ]]; then
find -mtime +7 -name "$f" -delete
else
find -mtime +1 -name "$f" -delete
fi
done
...甚至只是决定条件中的 mtime
参数。
for f in /my_files/recordings/*; do
if [[ -f "$f" && "$f" == 'file1.stream_'* ]]; then
mtime=+7
else
mtime=+1
fi
find -mtime "$mtime" -name "$f" -delete
done
您正在尝试同时做两件事;检查文件 ($f
) 是否存在并且是常规文件,并尝试将该测试的结果(这是一个 return 代码,而不是文本)与您提供的正则表达式(哪个也看起来它使用的是 glob 而不是正则表达式模式匹配)。这里也不允许将两者结合起来。 then
是另一个(内置)命令,您需要将它与 if
... 部分分开。
将支票分成应有的部分,并使用 glob 匹配或使用正则表达式,例如:
if [[ -f "${f}" && "${f}" == file1.stream_* ]]; then ...; fi
... 或者,对于正则表达式匹配:
if [[ -f "${f}" && "${f}" =~ file1\.stream_.* ]]; then ...; fi
另请注意,正则表达式匹配不会锚定到开头和结尾,因此与 glob 匹配不同,它实际上与 ^.*file1\.stream.*$
.
相同
我有一个这样的文件列表"file1.stream_2015-02-17.mp4",我一直在使用这个
删除这些文件#!/bin/bash
CONTENT_DIR=/my_files/recordings
find $CONTENT_DIR -mtime +1 -regextype posix-extended -regex '.*[.](mp4|tmp)$' -delete
到目前为止,这对我来说一直很好,但现在我想删除所有带有 file1.stream 的 1 天和所有带有 file2.stream 的 7 天
我一直在尝试这个,但我主要是不断出现错误
#!/bin/bash
CONTENT_DIR=/my_files/recordings/*
for f in $CONTENT_DIR; do
if [[ -f ${f} =~ 'file1.stream_*' ]] then
find -mtime +7 ${f} -delete
else
find -mtime +1 ${f} -delete
fi
done
但我一直收到此错误
syntax error in conditional expression
syntax error near `=~'
` if [[ -f ${f} =~ 'file1.stream_*' ]] then'
我不确定错误是什么,我已经四处寻找了几个小时,试图找到语法错误。感谢您的帮助
您的 if
条件中存在语法错误,=~
仅用于正则表达式。
您可以使用:
#!/bin/bash
for f in /my_files/recordings/*; do
if [[ -f "$f" && "$f" == 'file1.stream_'* ]]; then
find "$f" -mtime +7 -delete
else
find "$f" -mtime +1 -delete
fi
done
此外,如我上面的回答所示,glob 模式需要在引号之外。
你似乎在污染两种不同的结构。您需要分别检查它们。
[[ -f "$f" ]]
检查文件 $f
是否存在并且是一个普通文件。
[[ "$f" =~ regex ]]
检查 $f
中的字符串是否匹配正则表达式 regex
.
你可以这样组合它们:
if [[ -f "$f" && "$f" =~ regex ]]; then ...
或者简单地将其分成两个单独的比较:
if [[ -f "$f" ]] && [[ "$f" =~ regex ]]; then ...
另请注意 then
.
但是您拥有的模式是 glob 模式,而不是正则表达式,因此您可能想改用 glob 比较。
此外,您的字符串不是 find
的有效参数——我想您的意思是
if ...; then
find -mtime +7 -name "$f" -delete
: etc
或者也许(在这种情况下有点等价)
if ...; then
find "$f" -mtime +7 -delete
: etc
其中参数肯定需要用双引号引起来,否则 shell 将对其执行通配符扩展并用扩展结果替换变量,从而产生另一个语法错误。
最后,将模式放在变量中然后不加引号使用它并不是特别好的形式。该变量似乎没有任何用处,因此只需将模式内联到 for
循环中即可。
for f in /my_files/recordings/*; do
if [[ -f "$f" && "$f" == 'file1.stream_'* ]]; then
find -mtime +7 -name "$f" -delete
else
find -mtime +1 -name "$f" -delete
fi
done
...甚至只是决定条件中的 mtime
参数。
for f in /my_files/recordings/*; do
if [[ -f "$f" && "$f" == 'file1.stream_'* ]]; then
mtime=+7
else
mtime=+1
fi
find -mtime "$mtime" -name "$f" -delete
done
您正在尝试同时做两件事;检查文件 ($f
) 是否存在并且是常规文件,并尝试将该测试的结果(这是一个 return 代码,而不是文本)与您提供的正则表达式(哪个也看起来它使用的是 glob 而不是正则表达式模式匹配)。这里也不允许将两者结合起来。 then
是另一个(内置)命令,您需要将它与 if
... 部分分开。
将支票分成应有的部分,并使用 glob 匹配或使用正则表达式,例如:
if [[ -f "${f}" && "${f}" == file1.stream_* ]]; then ...; fi
... 或者,对于正则表达式匹配:
if [[ -f "${f}" && "${f}" =~ file1\.stream_.* ]]; then ...; fi
另请注意,正则表达式匹配不会锚定到开头和结尾,因此与 glob 匹配不同,它实际上与 ^.*file1\.stream.*$
.