2

我有一个目录,其中包含零个或多个文件,其名称如下

on_common_20131020.xml
on_common_20131021.xml
on_common_20131022.xml

等等。为了提取最近一个的日期戳,我知道我可以使用以下技巧

ls -rt on_common* | tail -n 1 | egrep -o '[0-9]{8}'

(虽然如果有更好的方法我很想知道)。现在的问题是,我想在脚本中捕获这个值,所以我有以下行:

RECENT=$(ls -rt on_common* | tail -n 1 | egrep -o '[0-9]{8}')

但是,目录中可能没有任何此类文件,在这种情况下ls会失败,我希望 RECENT 的值在这种情况下为 00010101。我知道如何使用 ' c1 || c2' 执行命令 c2 当且仅当命令 c1 失败,但无法找到任何可以给我相当于这个伪 Bash 的东西:

RECENT=$(ls -rt on_common* | tail -n 1 | egrep -o '[0-9]{8}') || '00010101'  # WRONG

是的,我可以用if...来做到这一点fi,但是有一个单一的表达形式吗?

编辑

原来只是缺少一个回声。Bash 语法说:

列表是一个或多个管道的序列,由运算符“;”、“&”、“&&”或“||”中的一个分隔,并可选地由“;”、“&”中的一个终止。 ',或换行符。

所以我很接近管道可以分开,||但右边的表达式||不是管道(它甚至不是命令)。

对于任何最终来到这里的人来说,另一个迂腐的笔记。当文件名中有日期戳时使用-tinls是非常危险的;有人可以触摸其中包含日期采样的文件名。我最终得到:

RECENT=$(ls -1 on_common* 2>/dev/null | sort -r | egrep -om1 '[0-9]{8}' || echo '00010101')

这是 Blue Moon 的(重定向到 dev/null)和 jaap 的答案(缺少内括号和 egrep 的 -m)的组合。

4

3 回答 3

2
    RECENT=$((ls -rt on_common* 2>/dev/null| tail -n 1 | egrep -o '[0-9]{8}') 
|| echo '0001-01-01')

会做c1 || c2你想要的。

请注意,我将 stderr 重定向到 /dev/null ( 2>/dev/null),以防万一ls失败。如果想查看错误,可以将其删除。

于 2013-10-27T22:24:00.090 回答
1

首先,您的搜索表达式可以短一些

ls -t on_common* | egrep -om1 '[0-9]{8}'

对于第二部分,这应该有效

RECENT=$(ls -t on_common* | egrep -om1 '[0-9]{8}' || echo "0001-01-01")
于 2013-10-27T22:25:04.997 回答
0

您可以使用这样的子外壳:

command1 |(command2 || <treatment if command2 fails>)
var=$(command1 |(command2 || <treatment if command2 fails>)) # to get the commands suite output in a variable

如果您只想在 command1 失败时执行治疗:

(command1 || <treatment if command1 fails>)|command2
var=$((command1 || <treatment if command1 fails>)|command2) # to get the commands suite output in a variable
于 2013-10-27T22:23:54.793 回答