我有一个问题是如何解决过去一个月我一直在努力解决的问题。场景如下:
我有一个基本目录,其中有多个子目录都遵循相同的子目录格式:
A/{B1,B2,B3}
所有B*
下都有pipeline/results/
目录结构。
所有这些results
目录中都包含多个*.xyz
个文件。这些*.xyz
文件具有基于其命名前缀的特定层次结构。命名前缀又取决于它们的处理距离。例如,它们可以是select.xyz
,select.copy.xyz
和select.copy.paste.xyz
,其中的操作是select
,copy
和paste
。我想做的是写一个ls | grep
或find
根据处理级别选择这些文件。
编辑:
处理渠道转为select
- > copy
- > paste
。 “处理最多”的文件将是其中大部分阶段作为其文件名中的前缀的文件。即select.copy.paste.xyz
的处理频率高于select.copy
,后者的处理速度高于select.xyz
例如,假设
B1/pipeline/results/
有select.xyz
和select.copy.xyz
,
B2/pipeline/results/
有select.xyz
B3/pipeline/results/
有select.xyz
,select.copy.xyz
和select.copy.paste.xyz
如何编写从每个子目录中选取处理最多的文件的ls | grep
/ find
?这应该会给我B1/pipeline/results/select.copy.xyz
,B2/pipeline/results/select.xyz
和B3/pipeline/results/select.copy.paste.xyz
。
关于如何考虑方法的任何指针都会有所帮助。谢谢!
答案 0 :(得分:1)
对于这个答案,我们将忽略目录结构的上半部分A/B{1,2,3}
。即使目录为.../pipeline/results/
,也会考虑某些A/B1/doNotIncludeMe/forbidden/pipeline/results
目录中的所有文件。我们假设文件扩展名xyz
是常量。
一个简单的解决方案是遍历目录并检查文件是否从后到前存在。也就是说,首先检查select.copy.paste.xyz
是否存在。如果文件不存在,请检查是否存在select.copy.xyz
,依此类推。这个脚本可能如下所示:
#! /bin/bash
# print paths of the most processed files
shopt -s globstar nullglob
for d in **/pipeline/result; do
if [ -f "$d/select.copy.paste.xyz" ]; then
echo "$d/select.copy.paste.xyz"
elif [ -f "$d/select.copy.xyz" ]; then
echo "$d/select.copy.xyz"
elif [ -f "$d/select.xyz" ]; then
echo "$d/select.xyz"
else
# there is no file at all
fi
done
它完成了这项工作,但并不是很好。我们可以做得更好!
#! /bin/bash
# print paths of the most processed files
shopt -s globstar nullglob
for dir in **/pipeline/result; do
for file in "$dir"/select{.copy{.paste,},}.xyz; do
[ -f "$file" ] && echo "$file" && break
done
done
第二个脚本与第一个脚本完全相同,但更容易维护,调整等等。这两个脚本都使用包含空格甚至换行符的文件和目录名称。
如果您的路径中没有空格,也可以使用以下(hacky,but loop-free)脚本。
#! /bin/bash
# print paths of the most processed files
shopt -s globstar nullglob
files=(**/pipeline/result/select{.copy{.paste,},}.xyz)
printf '%s\n' "${files[@]}" | sed -r 's#(.*/)#\1 #' | sort -usk1,1 | tr -d ' '