我有一个过程,它逐步创建目录,按升序为它们分配索引,并将结果存储在最后一次迭代的目录中,即索引最大的目录。鉴于完成该过程所需的迭代次数因数据集而异,我无法预测最后一个目录的索引。例如:
#Dataset 1 may produce
ls -d Dir*
... Dir4 Dir5
和
#Dataset 2 may produce
ls -d Dir*
... Dir34 Dir35
我想我可以创建一个包含所有目录名称的数组,复制最后一个目录并删除所有目录
ARR=($(ls -d Dir*))
cp ${ARR[@]:(-1)} LastDirectory #Preserve my results in LastDirectory
rm Dir*
但这肯定是搬起石头砸自己的脚。假设程序需要十次迭代才能完成。那么,Dir10 将包含我的结果。如果我列出目录并将它们传递给数组,Dir10 将不会位于最后的位置,并且将被淘汰。这是我想要避免的那种不可预测的行为!
#You can copy-paste this piece of code to replicate the problem:
mkdir Dir1 Dir2 Dir3 Dir4 Dir5 Dir6 Dir7 Dir8 Dir9 Dir10
ls -d Dir*
Dir1 Dir10 Dir2 Dir3 Dir4 ... Dir8 Dir9
ARR=($(ls -d Dir*))
echo ${ARR[@]:(-1)}
Dir9
有没有一种安全的方法来删除除索引最大的目录之外的所有目录?
笔记:我考虑过使用目录创建日期,但 Linux 似乎不支持此选项。
答案1
在我的 Ubuntu 上有-v
一个选项ls
。来自man ls
:
-v 对文本中的(版本)数字进行自然排序
作为替代方案,选项-V
也sort
用于处理版本号。我决定将它包含在我的答案中,因为它sort
可以用作过滤器。它在一般情况下可能很方便(例如,当您从文本文件或文本文件中获取目录列表时find
)。
像这样编写数组定义:
ARR=($(ls -d -v Dir*))
或这个:
ARR=($(ls -d Dir* | sort -V))
编辑:dave_thompson_085 的评论给出了有用的简化:
添加
-r
可将所需项目放在首位,更加方便访问${ARR[1]}
。
答案2
你能(手动)创建一个名为Dir1000
前你启动了这个过程,然后它创建了Dir1001
,Dir1002
等等?
如果这个过程是这样运作的,那是不是就很明显、很简单了?
答案3
既然你无法更改创建目录的程序(如你所说),那么能否让它为每个任务写入不同的输出目录?因此,你应该
Task1
+ Dir1
+ Dir2
Task2
+ Dir3
+ Dir4
否则,可能更安全的做法是看看内容目录。中间目录和包含结果的最后一个目录之间有区别吗?如果结果只在最后一个目录中,您可以使用此信息找出哪个目录,将结果复制走并删除其他目录。
答案4
如果您同意按日期对目录进行排序(听起来索引最高的目录也是最近创建的目录),您可以执行以下操作:
ls -1td Dir* | tail -n +2
列出了除最新目录之外的所有目录。要删除这些目录,请执行以下操作:
rm $(ls -1td Dir* | tail -n +2)
这里的关键参数是-t
按日期排序。