2011-02-16 93 views
3

因此,我有一个bash脚本,它会查找一系列子目录,查找包含某个字符串的文件,然后为该字符串的出现打印文件总计和目录总计。代码如下。在BASH脚本中按顺序读取文件

for dir in $(find * -type d); do 
    echo "directory: $dir" >> $OUT 
    for f in $(find $dir/* -type f); do 
    echo -n "$(basename $f) " >> $OUT 
    grep -c -h $1 $f >> $OUT 
    done 
    echo -n "directory total: " >> $OUT 
    grep -c -h $1 $dir/*.* | awk '{SUM += $1} END {print SUM}' >> $OUT 
    done 

当它这样做,如果我在10个文件中读取,它会列出他们在文本文件FILE1.TXT,file10.txt,FILE2.TXT等等

有任何方式,我可以使它打印file1.txt,file2.txt,file3.txt等,并有第10个文件实际列出的顺序?

我是BASH的新手,所以我只是想知道有没有人知道这件事。任何帮助不胜感激。是的,这些文件实际上被命名为file1.txt,file2.txt等。这主要是为了熟悉BASH脚本。

+1

由于这个原因,我通常命名文件`file01.txt`,`file02.txt`,...`file99.txt`。 – 2011-02-16 08:53:36

回答

2
find -type d | while read -r dir 
do 
    echo "directory: $dir" 
    find "$dir" -maxdepth 1 -type f | sort --version-sort | while read -r f 
    do 
     echo -n "$(basename "$f") " 
     grep -c -h "$1" "$f" 
    done 
    grep -c -h "$1" "$dir/*" | awk -F: '{SUM += $1} END {print "directory total:", SUM}' 
done > "$OUT" 
  • 移动重定向到循环结束
  • 使用while read而不是for的情况下,文件名中包含空格(可以采取额外的措施,以防止一些不常见的奇怪的字符,如果需要的话)
  • 引用您的变量也保护空白
  • 使用-maxdepth 1与内find避免重叠,重复
  • 使用sort --version-sort获取文件名的顺序,你想
  • AWK可以在它打印的总
  • 现场隔离物需要被设置为一个冒号
  • 相反的echo -n "$(basename "$f") "你可以使用相同的时间打印文本echo -n "${f##*/} "
0

这些文件按字典顺序排序(这就是file10在file1之后的原因)。如果文件名为file<num>,则更容易 - 您使用sort -k1.5n。在一般情况下,它是棘手 - 会有一些涉及解析,判断你的情况是一般:)

几点:

也许你不必find $dir/* -type ffind $dir -type f。在前一种情况下,您使用shell的globbing功能。那么子目录呢?

顺便说一句,你可以把它改写如下跳过垃圾邮件每一行与>> $OUT

for dir in $(find * -type d); do 
    echo "directory: $dir" 
    for f in $(find $dir/* -type f); do 
    echo -n "$(basename $f) " 
    grep -c -h $1 $f 
    done 
    echo -n "directory total: " 
    grep -c -h $1 $dir/*.* | awk '{SUM += $1} END {print SUM}' 
done >> $OUT 
+0

谢谢你,这样的提示太棒了! – 2011-02-16 09:06:32

0

改变这一行:

for f in $(find $dir/* -type f); do 

这一行:

for f in $(find $dir/* -type f | sort --numeric-sort); do 
+1

我相信数字排序不会帮助,因为密钥的开头不是数字。 – 2011-02-16 09:13:10

0

所以我想我已经在你们的帮助下找到了它,并且还有一些修补。不知道这是最好的方式,但我结束了这方面的工作...

for f in $(find $dir -type f | cut -d. -f1 | cut -d'e' -f3 | sort -n); do 
    echo -n " file$(basename $f).txt: " 
    grep -c -h $1 $dir/"file$f"'.txt' 
    done 

显然,这是非常具体的文件名我有,但它是更多地了解一件好事。由于