【问题标题】:Bash: Check If A Command Returns A Certain Value [duplicate]Bash:检查命令是否返回某个值
【发布时间】:2017-08-21 02:25:01
【问题描述】:

我正在尝试编写一个.sh 脚本,它会在某一时刻检查当前目录中是否有一个或多个文件与*\_??\_??\_64kbs.mp3 匹配

或者,使用正则表达式^.*\_..\_..\_64kbs\.mp3$

这是对命令的一次尝试:

if [ 'ls *_??_??_64kbs.mp3 2>/dev/null | wc -l ' == 0 ];
then echo "nothing";
else echo "something";
fi

我知道

'ls *_??_??_64kbs.mp3 2>/dev/null | wc -l'

在这种情况下,只返回数字 9 到终端,因为有 9 个匹配项。如果我删除第一个“?”,它会返回 0,就像它应该返回的那样,因为没有与该表达式匹配的文件名。但是上面 if 表达式的输出总是“某物”。

编辑: 有人要求我要匹配的完整示例文件名。这是一个:

George-1983_1A_01_64kbs.mp3

【问题讨论】:

  • 能否举一个完整的示例文件名作为例子?
  • 看看$?
  • 刚刚在问题中添加了一个示例文件名,Inian。
  • 哎呀,我不明白你的建议。
  • 您正在检查字符串 'ls ....' 是否等于 0,但它从来都不是。

标签: linux bash shell conditional ls


【解决方案1】:

我找到了一个似乎可行的解决方案。用 $() 代替引号将命令包装起来。

if [ $(ls *_??_??_64kbs.mp3 2>/dev/null | wc -l) == 0 ];
then echo "nothing";
else echo "something";
fi

我之前尝试过类似的方法,但它似乎不起作用,但一定是语法错误。在这种情况下,它正在工作。

【讨论】:

  • 这显然不是正确的做法,一般不推荐解析ls的输出,见Why you shouldn't parse the output of ls
  • 似乎您尝试过'ls ...'(文字字符串“ls ...”)$('ls ...')(名为“ls .... ",文件和因此命令中的空格)永远不会 $(ls ...)`ls ...` (两者都有效)。
  • 同样管道到wc -l 是一种非常常见的反模式。见iki.fi/era/unix/award.html#wc
【解决方案2】:

您显然将 globregex 匹配混淆了,* 是一个纯 glob 构造,可以在如下循环中使用

fileNamePattern="*_??_??_64kbs.mp3"
for file in *.mp3; do
    [[ $file == $fileNamePattern ]] && echo "$file matches"
done 

?* 的含义在regex 上下文中使用时是不同的,其中我们使用.* 来匹配一个部分,.{} 来表示其出现可由下式决定的任何字符比如{}里面的值,

fileNameRegex=".*_.{2}_.{2}_64kbs.mp3"
for file in *.mp3; do
    [[ $file =~ $fileNameRegex ]] && echo "$file matches"
done

~bash 正则表达式运算符(支持从 bash 版本 4.0 开始)您需要匹配 regex 而不是 glob .

【讨论】:

  • 感谢您的回答,这很有效,但我显然“没有”将 glob 与正则表达式混淆。您可以在我的问题的开头看到我建议了一个与示例中使用的 glob 等效的正则表达式。它和你的一样,只是我明确写了 .. 而不是 .{2},并且我用 ^ 开头并以 $ 结尾。
  • @MatthewJendrasiak:欣赏!考虑到使用 glob 和 regex 方法,周围有一些混乱。如果这解决了您的问题,请不要忘记点赞并接受它,以使其对未来的读者有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多