我需要一些脚本方面的帮助。我当前正在尝试选择满足文件名特定要求的 PDF 文件,以便将其移动到其他位置。
我尝试选择的文件名格式具有单独的部分,如下例所示:
I_XXX_PACK_6788669_6_9358869.pdf
我想做的是仅选择文件名中最后一部分的文件(例如9358869
)并忽略目录中的所有其他 pdf 文件。
可以用 Unix 工具(POSIX find、sed、grep 等)来完成吗?我现在的主要问题是尝试只获取文件名中由 6 个分隔部分组成的一个文件,并忽略所有其他文件。
- 另外,是否可以只选择系统时间前 1 小时创建的文件?我已经在其他文件类型上使用 sed 来检查时间,但没有在 pdf 文件上使用。所以我不确定这是否可能
答案1
您有诸如 之类的文件I_XXX_PACK_6788669_6_9358869.pdf
,并且您只需要那些_
与六个分隔部分匹配的文件,其中最后一个部分是9358869
.
这将匹配至少六个_
以 分隔的部分(*
是匹配零个或多个字符的通配符,包括_
)以 结尾9358869.pdf
:
*_*_*_*_*_9358869.pdf
您可以使用 查找过去一小时内修改(但未创建)的文件find
,但此扩展名不是 POSIX:
find /path/to/directory -type f -mmin -60
为了允许 POSIX,您需要使用-newer {file}
,并设置{file}
为适当的年龄。 POSIX 不提供将文件的修改日期时间设置为过去一小时的可靠方法,但正如您标记的那样巴什我们可以用它:
printf -v curr '%(%s)T'
past=$(printf '%(%Y%m%d%H%M)T\n' "$((curr - 60*60))")
touch -t "$past" /path/to/timestamp
find /path/to/directory -type f -newer /path/to/timestamp
最后,将两者合并:
touch -t "$(printf -v curr '%(%s)T'; printf '%(%Y%m%d%H%M)T\n' "$((curr - 60*60))")" /path/to/timestamp
find /path/to/directory -type f -newer /path/to/timestamp -name '*_*_*_*_*_9358869.pdf'
答案2
find . -name '[!_]*_*_*_*_*_*[!_].pdf' ! -name '*_*_*_*_*_*_*' ! -name '*__*'
.pdf
将报告名称以 5 且仅 5 个_
字符结尾且根名称的每个_
- 分隔部分不为空的文件(任何类型) 。
对于某些find
实现,名称无法在当前语言环境中解码为文本的文件也将被排除。
为了限制在最后一个小时内修改的内容,正如 Chris 所说,某些实现支持的-newermt '1 hour ago'
,-mmin 60
或-mtime -1m
不是标准的,并且 POSIXfind
除了 之外没有等效项-newer some-file-with-a-last-modification-time-one-hour-ago
。
以 POSIX 方式创建一个搜索参考时间的常用方法是:
TZ=XXX0 touch -t "$(TZ=XXX1 date +%Y%m%d%H%M.%S)" some-file-with-a-last-modification-time-one-hour-ago
在时区(我们命名的时区,但名称与此处无关)date
中调用where ,我们将其定义为比 UTC 晚 1 小时,并将产生的时间戳解释为UTC 时间(在也称为时区,但比 UTC 晚 0 小时) UTC)因此最终创建了一个一小时前的文件。XXX
touch
date
XXX
之后您可以执行以下操作:
find . -name '[!_]*_*_*_*_*_*[!_].pdf' \
! -name '*_*_*_*_*_*_*' \
! -name '*__*' \
-newer some-file-with-a-last-modification-time-one-hour-ago
如果像你的巴什标签表明,您不限于使用 POSIXsh
语法,那么您可以使用zsh
不需要任何外部实用程序即可完成所有操作的地方:
set -o extendedglob
print -rC1 -- **/([^_]##_)(#c5)_[^_]##.pdf(ND-.mh-1)
在哪里:
**/
匹配任何级别的子目录(包括0)[^_]
匹配除以下字符之外的任何字符_
x##
匹配一个或多个x
es,与 相同x(#c1,)
。x(#c5)
正好匹配 5 个x
esN
如果没有匹配项,ullglob 将扩展为空,而不是报告错误。D
otglob 包含隐藏的.
和mh-1
常规文件,最后修改时间不到一小时前(或将来),并-
在符号链接解析后完成该检查。print -rC1 --
print
其论据r
在 aw 和1
C
olumn 上。
如果您想将匹配限制为最后 3 部分必须是十进制整数的文件,您可以将其更改为:
set -o extendedglob
print -rC1 -- **/([^_]##_)(#c3)<->_<->_<->.pdf(ND-.mh-1)
其中<->
是<1-20>
数字匹配运算符的形式,但这里没有边界,因此匹配任何十进制整数(您也可以编写一个或多个 ASCII 十进制数字的任何序列[0-9]##
)。
¹ 您可以添加-type f
仅考虑类型的文件常规的(与 fifo、设备、目录、管道相反......)但请注意,它还会排除常规文件的符号链接。要包含这些,您需要-xtype f
,但这也是一个非标准(GNU)扩展。