我有一组目录和子目录如下。
aaa/180809_1047
aaa/180915_0055
aaa/181012_1545
aaa/xyz
bbb/180809_1047
bbb/180915_0055
bbb/181012_1545
bbb/181105_0000
bbb/xyz
.
.
.
zzz/180821_1555
zzz/181004_2355
zzz/xyz
大部分子目录都是 YYMMDD_HHMM 格式。在这里,我试图从每个父目录中打印格式为 YYMMDD_HHMM 的子目录(最新)。以下是我的要求。
输出:
aaa/181012_1545
bbb/181105_0000
zzz/181004_2355
我使用了如下的查找命令:
find ./*/ -type d -maxdepth 1 -mindepth 1 -name "???????????" | sort -u | tail -1
"????????????"
--> 这是打印符合格式 YYMMDD_HHMM 的目录。
执行此命令后,我只得到了。
zzz/181004_2355
最佳答案
我会使用 for
循环在 bash 中本地执行此操作,而不是使用 find
。
老实说,我不记得 bash 是否对处理 glob 的顺序做出任何 promise 。因此,使用您包含的示例日期,这是一个使用 [[
:
$ declare -A last=(); for a in *; do for b in $a/[0-9]*/; do [[ $b > $last[$a] ]] && last[$a]=$b; done; done; declare -p last
declare -A last=([bbb]="bbb/181105_0000/" [zzz]="zzz/181004_2355/" [aaa]="aaa/181012_1545/" )
请注意,这里的限制模式是$a/[0-9]*/
,这对您的示例数据来说已经足够了。当然,您可以根据需要限制它,使用字符类并消除 glob。
另请注意,此模式中的尾随 /
可确保您只会匹配属于目录的内容。这会将 /
放在 $last
数组中每个结果的末尾。如果需要,您可以进行后处理:
$ for i in "${!last[@]}"; do last[$i]="${last[$i]%/}"; last[$i]="${last[$i]#*/}"; done
$ declare -p last
declare -A last=([bbb]="181105_0000" [zzz]="181004_2355" [aaa]="181012_1545" )
为了便于阅读,这里将一行分成多行。 :)
# Create an associative array. Requires bash 4+.
declare -A last=()
# Step through the top-level directories
for a in *; do
# Step through the second level directories
for b in "$a"/[0-9]*/; do
# Compare and record as required
[[ $b > $last[$a] ]] && last[$a]="$b"
done
done
# Print the result
declare -p last
关于linux - 如何在每个父目录中打印最后一个目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53149509/