我正在尝试创建一个 bash 脚本,该脚本会删除目录中最旧的文件,并使用变量设置要保留的文件数量。
我的第一步是计算要保留的超过设定数量的 10 个最新文件的数量:
#!/bin/bash
# How many files in the current directory are older than the retained files
olderThanRetain=$(find -maxdepth 1 -type f | sort -r | sed -e '1,10d' | wc -l)
echo $olderThanRetain
工作正常。
但是当我尝试设置一个变量来保存要保留的文件数量时:
#!/bin/bash
retain=10
# How many files in the current directory are older than the retained files
olderThanRetain=$(find -maxdepth 1 -type f | sort -r | sed -e "1,(( $retain ))d" | wc -l)
echo $olderThanRetain
但这给了我错误:
sed: -e expression #1, char 3: unexpected `,'
我错过了什么?
答案1
由于逗号不是特殊字符,因此bash
根本不需要引用此表达式,您可以简单地使用:
sed 1,${retain}d
为了避免出现奇怪的文件名问题(想象一下带有换行符的文件名),请使用0
作为行分隔符。另外,我不太确定你在那里排序的是什么,要按上次访问时间反向排序,我会这样做:
find -maxdepth 1 -type f -printf "%A@ %p\0" | sort -zr | sed -z 's/[^ ]* //;'1,${retain}d
您可以使用 更改0
为换行符tr \\0 \\n
。要计算可以使用的零分隔行tr -cd '\0' | wc -c
,请参阅计算文件中空分隔项的数量 · U&L。
解释
find -maxdepth 1 -type f -printf "%A@ %p\0"
– 查找-type f
当前目录下的每个文件( ),而不搜索子目录(-maxdepth 1
)并打印"%A@ %p\0"
(不带换行符!)。
%A@
替换为文件的访问时间自纪元以来的秒数、%p
文件名\0
和空字符, 看man find
/表达式/动作/-printf以获取完整的转义和指令列表。sort -zr
–按相反顺序z
对电子分隔数据进行排序r
sed -z 'a;b
sed
–在每个以z
ero 为条目分隔符的条目上运行表达式 a 和 b
您只需引用 shell 的特殊字符,请参阅我在这里引用的帖子。事实上在这种情况下您唯一需要引用的是;
(通过转义或使用单引号或双引号),所以sed -z s/[^ ]* //\;1,${retain}d
也可以。s/[^ ]* //
–s
用不包含空格字符的第一个字符串 (= 直到第一个空格字符的所有内容) 和其后跟的空格字符替换为空字符 (= 删除它)1,${retain}d
– 删除第一个$retain
条目