2010-02-19 30 views
63

场景:Linux Shell脚本对于目录中的每个文件抓取文件名并执行程序

Linux系统中的文件夹。我想遍历文件夹中的每个.xls文件。

此文件夹通常由各种文件夹,各种文件类型(.sh,.pl,.csv,...)组成。

我想要做的就是循环遍历中的所有文件,并仅在.xls文件中执行程序。

编辑:

的问题是节目,我必须执行是“xls2csv”从.xls的转换为.csv格式。因此,对于每个.xls文件,我必须抓取文件名并将其附加到.csv。

举例来说,我有一个TEST.XLS文件来回xls2csv的论点是:xls2csv test.xls test.csv

难道我有意义吗?

回答

156

的bash:

for f in *.xls ; do xls2csv "$f" "${f%.xls}.csv" ; done 
+5

+1简单 – Tom

+0

简直太棒了!完美的作品!非常感谢! – ThinkCode

+5

这正是我所寻找的完全不同的原因。一点编辑,对我的特定需求来说是完美的。谢谢= D 对于任何人不明确这是什么:$ {f%.ext}替换文件名没有扩展名,所以在这个例子中,它会呈现为“filename.csv”,而不是“ filename.xls.csv”。 – Frungi

9

看看find命令。

你所寻找的是类似

find . -name "*.xls" -type f -exec program 

帖子编辑

find . -name "*.xls" -type f -exec xls2csv '{}' '{}'.csv; 

将执行xls2csv file.xls file.xls.csv

接近你想要什么。

+0

'find -maxdepth 1'排除子文件夹。这也将'test.xls'转换为'test.xls.csv'而不是'test.csv'。所以不*相当* OP所要求的,但非常接近。 – ephemient

+0

使用'{}'作为参数的子字符串而不是整个参数是GNU扩展名,不受POSIX规范中'find'的保证。因此,这个答案不一定可以移植到非GNU平台。 –

2
find . -type f -name "*.xls" -printf "xls2csv %p %p.csv\n" | bash 

的bash 4(递归)

shopt -s globstar 
for xls in /path/**/*.xls 
do 
    xls2csv "$xls" "${xls%.xls}.csv" 
done 
+0

优秀的解决方案。我使用它来允许我编写haml/scss,并在设计时为node.js项目构建html/css。 –

+1

如果你不相信你的文件名不包含'$(rm -rf /)'......或者只是空白的东西,那么这是非常危险的。 –

9
for i in *.xls ; do 
    [[ -f "$i" ]] || continue 
    xls2csv "$i" "${i%.xls}.csv" 
done 

do检查第一行,如果 “匹配” 文件确实存在,因为在壳体在您的for中没有任何匹配项,do将与“* .xls”为$i。这对你的xls2csv可能会很糟糕。

相关问题