我只能从bash球中选择一个结果吗?


14

我正在尝试编写一个脚本来自动执行一些输出报告。日志文件(目前正在将来被标准化)存储在这种路径结构中:

/<root_path>/<process_one_path>/logs/<time_date_stamp>/<specific_log_file>

/<root_path>/<process_two_path>/logs/<different_time_date_stamp>/<specific_log_file>

除时间标记外,路径的每个部分都是已知的,时间标记始终是文件夹中的最新标记。

如果我尝试使用通配符代替时间戳记,则会得到多个结果,例如:

> ls /<root_path>/<process_two_path>/logs/* [tab]
20130102-175103
20130118-090859
20130305-213506

我只希望它返回最新版本,Bash可以吗?

NB(我没有zsh,而且听起来很可爱,我怀疑我们是否会成功使用它)

Answers:


9

以下内容在bash 4.2中起作用:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[-1]}"

如果您的bash是较旧的版本:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[${#list[@]}-1]}"

这绝对可以在我的家用计算机上运行,​​但是我不能保证它可以正常工作吗?
Pureferret

@Pureferret可能无效的部分是负数组索引(-1)。这是在bash 4.2中添加的。RHEL5可能是最受支持的最早的主流企业发行版,它使用bash 4.2.20。
帕特里克

1
较早版本的bashhave:"${list[@]: -1}"like in ksh93[-1]来自zsh)。
斯特凡Chazelas

@Patrick-RHEL5使用bash 3.2。RHEL 3和4在延长寿命后仍受支持。
jordanm

1
@Pureferret您也可以对数组长度进行算术运算,请参见我的编辑。
吉尔斯(Gilles)'所以

10

POSIXly:

 set -- /<root_path>/<process_two_path>/logs/*
 shift "$(($# - 1))"
 printf '%s\n' "$1"

自从您提到zsh

 print -r /<root_path>/<process_two_path>/logs/*([-1])

4

在bash for loop中使用bash glob。像这样:

for filename in <logdir>/*; do :; done; echo "$filename"

这取决于bash会按字母顺序排序的glob扩展。阅读bash手册以获取更多信息。请注意,这取决于LC_COLLATE。这也取决于以下事实:filename在循环终止后,仍包含最后一个值。

如果您希望文件名带有最旧的时间戳,则可以这样操作:

for filename in <logdir>/*; do echo "$filename"; break; done

1

-1是管道中的默认值,并且ls输出应该已经排序:

ls | tail -n1

如果其他人正在寻找如何以交互方式插入第一个或最后一个结果,则可以在.inputrc中绑定menu-complete或menu-complete-backward:

"\e\t": menu-complete
"\e[Z": menu-complete-backward # shift-tab

如果启用了show-all-if-ambiguous,set completion-query-items 0则在有101个或更多结果时删除提示,并set page-completions off禁用寻呼机。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.