for循环中的Bash语法错误

时间:2015-02-17 07:38:37

标签: bash if-statement for-loop syntax

我有一个像这样的文件列表" 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'

我不确定错误是什么,我一直在寻找几个小时试图找到语法错​​误。谢谢你的帮助

3 个答案:

答案 0 :(得分:2)

你似乎污染了两种不同的结构。你需要单独检查它们。

[[ -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

答案 1 :(得分:1)

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模式需要在引用之外。

答案 2 :(得分:0)

你试图一次做两件事;检查文件($f)是否存在且是否是常规文件,并尝试将该测试的结果(返回代码,而不是文本)与您给出的正则表达式进行比较(看起来也是如此)使用glob而不是正则表达式模式匹配)。这里也不允许将两者结合起来。 then是另一个(内置)命令,您需要将其与if ...部分分开。

将支票分成它应该的部分,并使用全局匹配,或使用正则表达式,例如:

if [[ -f "${f}" && "${f}" == file1.stream_* ]]; then ...; fi

...或者,对于正则表达式匹配:

if [[ -f "${f}" && "${f}" =~ file1\.stream_.* ]]; then ...; fi

另请注意,正则表达式匹配不会锚定到开头和结尾,因此,与全局匹配不同,它实际上与^.*file1\.stream.*$相同。