我曾经见过一些使用 ls 的单行代码,但我想避免这样做。
我正在编写一个脚本,将代码复制到带有时间戳的文件夹中的服务器。“当前”版本始终符号链接到一个常量路径。这样,如果出现任何问题,我就可以回滚。现在,每次部署都会创建一个新文件夹,但我只想保留最新的 3 个文件夹。
这是我现在的版本:
ls -tp | grep '/$' | grep -v 'current\|shared' | tail -n +4 | xargs -d '\n' rm -rf --
这是在包含文件夹中执行的,排除文件,以及我想要保留的两个文件夹“当前”和“共享”(当前实际上是前面提到的符号链接),并删除除按排序的最新 3 个之外的所有内容ls -t
。
有什么方法可以不用ls
而只使用 bash 和 gnu 工具链来做到这一点?
所有用于修剪的文件夹均按照以下格式命名:
$timestamp.$branch.$sha1
其中 SHA1 和分支是来自 git 的有关具体部署内容的信息。
该服务器运行 Ubuntu Xenial。
编辑:提供一些文件夹的示例
这是部署文件夹中的列表,现在的样子:
drwxr-x--- 13 app www-data 4096 Mar 29 00:10 1490738956.develop.b806/
drwxr-x--- 13 app www-data 4096 Mar 29 00:19 1490739485.develop.ae01/
drwxr-x--- 14 app www-data 4096 Mar 29 03:33 1490751118.develop.f5b0/
lrwxrwxrwx 1 app www-data 40 Mar 29 03:33 current -> /home/app/deploy/1490751118.develop.f5b0/
drwx------ 5 app root 4096 Mar 10 04:12 shared/
答案1
如何删除文件夹中除最近的 3 个子文件夹之外的所有子文件夹?
您可以使用find
、、sort
和最后:awk
xargs
rm
find * -maxdepth 0 -type d -not -path "current" -not -path "shared" -printf "%T@ %p\n" | sort -nr | awk 'NR > 3 {print $2}' | xargs rm -rf
分解:
find
用于查找文件和目录并可能对其执行命令的多功能工具
*
考虑当前文件夹中的元素
-maxdepth 0
不要查看子文件夹
-type d
查找目录
-not -path "current"
排除名为“current”的目录
-not -path "shared"
排除名为“shared”的目录
-printf "%T@ %p\n"
打印结果,在目录名称前面附加时间戳。在您的情况下可以省略此操作,因为目录已经带有时间戳。
| sort -nr
根据时间戳以相反的顺序对列表进行排序
| awk 'NR > 3 {print $2}'
打印除前三个结果之外的所有结果,忽略之前添加的时间戳。这是您选择要保留多少结果的地方,只需替换数字即可3
| xargs rm -rf
删除这些目录及其所有内容
编辑:在您的例子中,由于目录名称已经以时间戳开头,因此无需再次添加时间戳即可sort -nr
生效。请注意,awk
语法需要进行相应的编辑。
find * -maxdepth 0 -type d -not -path "current" -not -path "shared" | sort -nr | awk 'NR > 3 {print $0}' | xargs rm -rf
答案2
最基本的形式
touch -t 201003160120 some_file
find . -maxdepth 0 -type d ! -newer some_file -name \*.develop.\* -delete
摘自https://serverfault.com/questions/122824/linux-using-find-to-locate-files-older-than-date
! -newer some_file
告诉它匹配任何不比 'some_file' 更新的内容
-name \*.develop.\*
告诉它只匹配符合此模式的名称(*.develop.*)
-delete
- 我希望这不需要解释,当心!(测试时使用-print!)
-type d
- 仅限目录
-maxdepth 0
- 不要递归到子文件夹。