2013-09-30 64 views
1

我想在Linux中编写一个shell脚本,它循环遍历所有目录和子目录,并捕获所有文本文件一次。下面是我到目前为止,我稍微落后于这一个逻辑。有人能帮我一把吗?感谢Linux Shell脚本文件和目录循环

脚本需要1个参数 如:./script.sh目录名

#!/bin/bash 

echo "Directory $1" 

cd $1 
for f in *.txt 
do 
cat $f 
done 

IM不确定如何进入子目录从这里,因为可以在每个子目录无限量。

回答

4

使用find

如果你的操作系统支持POSIX的现代版:

find "$1" -type f -name '*.txt' -exec cat '{}' + 

...或者,如果它不:

find "$1" -type f -name '*.txt' -exec cat '{}' ';' 

...或者,如果你想成为低效(或有更有趣的使用情况,你还没有告诉我们),和您的find支持-print0 ...

find "$1" -type f -name '*.txt' -print0 | \ 
    while IFS='' read -r -d '' filename; do 
    cat "$filename" 
    done 

不要忽略-print0 - 否则,恶意命名的文件(在其名称中带有换行符)可以向流中插入任意名称(最坏的情况下),或者隐藏处理(最好)。

+0

什么是print0? – NewFile

+0

@NewFile,'-print0' NUL分隔名称,而不是换行符分隔。 –

+0

文件夹名称?find $ 1 -type -f -name'* .txt'-exec cat'{}'+ –

2

您可以使用find或递归。

示例使用递归:

dump_files() 
{ 
    for f in $1/*; do 
     if [[ -f $f ]]; then 
      cat $f 
     elif [[ -d $f ]]; then 
      dump_files $f 
     fi 
    done 
} 
+0

我做了你写的东西,但我得到了语法错误fi – NewFile

+0

是的,我写了一个语法错误,但@JohnKugelman修复了它。 –

0

改变的环路与

for f in $(find . -name *.txt);do 
    cat $f 
done 
+0

-1;这是积极有害的/创造错误。请参阅http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29(除了扩展中缺少引用外) –

+0

与原始代码相同的问题:for * in * .txt – michael501

+0

Untrue。 '* .txt'中的f是安全的。阅读链接页面。 –

2
find . -name '*.txt' -print0 | xargs -0 cat 

如果你想要一个特定的目录,以目录的完整路径替换.find获取以扩展名.txt结尾的文件,并将其传送到运行命令catxargs-0选项xargs按字面输入。 -print0模式适用于此...

+0

如果你有一个足够现代的发现有'-print0',为什么不使用'-exec {} +'表单(它像xargs一样,也尽可能多的将参数放到每个'cat'命令行上)? –

+0

不要不同意你,@CharlesDuffy。我正在采取不同的选择,就是这样。 – iamauser