将文件名导出到临时文件bash

时间:2015-04-20 19:07:51

标签: regex bash unix filenames

我在多个目录中有很多文件都具有以下文件名设置:

prob123456_01

我想删除每个文件名的尾部“_01”并将它们导出到临时文件。我究竟如何删除尾随的“_01”以及导出?我对脚本非常陌生,所以任何帮助都会非常感激!

2 个答案:

答案 0 :(得分:2)

当您使用标记时,我会假设您可以使用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及其喜欢的非常基本的部分,所以看一两个教程并熟悉这些和其他一些教程可能是个好主意;)