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.*$.

相同