在 bash 脚本中,如何将变量整数传递给“sed -e”命令(18.04)

在 bash 脚本中,如何将变量整数传递给“sed -e”命令(18.04)

我正在尝试创建一个 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;bsed–在每个以zero 为条目分隔符的条目上运行表达式 a 和 b
    您只需引用 shell 的特殊字符,请参阅我在这里引用的帖子。事实上在这种情况下您唯一需要引用的是;(通过转义或使用单引号或双引号),所以sed -z s/[^ ]* //\;1,${retain}d也可以。
    • s/[^ ]* //s用不包含空格字符的第一个字符串 (= 直到第一个空格字符的所有内容) 和其后跟的空格字符替换为空字符 (= 删除它)
    • 1,${retain}d– 删除第一个$retain条目

相关内容