我在多个目录中有很多文件都具有以下文件名设置:
prob123456_01
我想删除每个文件名的尾部“_01”并将它们导出到临时文件。我究竟如何删除尾随的“_01”以及导出?我对脚本非常陌生,所以任何帮助都会非常感激!
答案 0 :(得分:2)
当您使用bash标记时,我会假设您可以使用globstar
shopt -s globstar # enable globstar
for f in **_[0-9][0-9]; do echo "${f%_*}"; done > tmp
启用globstar
后,模式**_[0-9][0-9]
将匹配当前目录和所有子目录中以_
结尾的任何文件,后跟任意2位数字。 ${f%_*}
使用bash的内置字符串操作功能删除文件名的末尾。
更好的是,正如Charles Duffy建议(谢谢),您可以使用数组而不是循环:
files=( **_[0-9][0-9] ); printf '%s\n' "${files[@]%_*}"
数组填充的文件名与之前的模式相同。 ${files[@]%_*}
从数组的每个元素中删除最后一部分,并将它们全部作为参数传递给printf
,它将每个结果打印在一个单独的行上。
这些方法中的任何一种都可能比使用find
更快,因为一切都在shell中完成,而不执行任何单独的进程。
之前我曾建议使用模式**_{00..99}
,尽管由于几个原因这并不理想。效率较低,因为它扩展为**_00
,**_01
,**_02
,...
,**_99
。此外,除非启用了另一个选项nullglob
,否则将不会将这100个不匹配的模式中的任何一个字面包含在输出中。
取决于您使用[0-9]
还是[[:digit:]]
,但后者的优势在于它匹配定义为数字的所有字符,这可能会因您的语言环境而异。如果这不是一个问题,我会选择前者。
答案 1 :(得分:0)
如果我理解正确,您需要一个没有尾随_01
的文件名列表。以下是这样的:
find . -type f -name '*_01' | sed 's/_01$//' > tmp.lst
find . -type f -name '*_01'
查找当前目录中的所有文件及其后代目录,查找名称以_01
结尾的文件。
|
是所谓的管道,将左侧呼叫的结果交给右侧呼叫。
sed 's/_01$//'
从每个文件名的末尾删除_01
。
> tmp.lst
将结果写入文件tmp.lst
这些都是使用bash
及其喜欢的非常基本的部分,所以看一两个教程并熟悉这些和其他一些教程可能是个好主意;)