使用shell脚本遍历子目录并执行grep

时间:2013-10-07 19:07:27

标签: shell grep

我的目录具有以下结构(在Mac上)

main_folder/
 |_folder1/
 |_folder2/
 |_folder3/

每个子文件夹都有一个名称相同的文件“classFile.trans” 我想遍历子文件夹并对文件classFile.trans执行grep。但我不知道如何将输出新文件保存在相应的子文件夹中。感谢

#!/bin/bash
find file in ./main_folder/**classFile.trans; do

grep -v "keyword" $file > newClassFile.trans     #how do I save the output new file in the corresponding sub folder?

done

3 个答案:

答案 0 :(得分:2)

可能最容易在每个子目录中运行grep:

#!/bin/bash
for d in ./main_folder/*; do
 ( cd $d; 
   file=classFile.trans
   test -f $file && grep -v "keyword" $file > newClassFile.trans
 ) 
done

括号使循环体在新的子shell中迭代,因此主shell的工作目录不会改变。但是,这会使grep的错误消息毫无用处。例如,如果任何classFile.trans不可读,则错误消息将不指示哪个目录。所以最好这样做:

for d in ./main_folder/*; do grep -v keyword $d/$file > $d/$newfile; done

答案 1 :(得分:1)

我会用

#!/bin/bash
for file in `find ./main_folder/ -name "classFile.trans" `; do 
   newFile=`dirname $file`/newClassFile.trans; 
   grep -v "keyword" $file > $newFile
done

答案 2 :(得分:0)

find命令具有-exec*个标志,允许它为匹配的每个文件运行命令。对于你的情况,你会这样做:

find ./main_folder -name classFile.trans \
     -execdir $SHELL -c "grep -v '$keyword' {} >newClassFile.trans" \;

(添加了\和换行符,因此无需滚动即可读取整个命令)

打破各种争论:

  • -name classFile.trans搜索名为classFile.trans
  • 的所有文件
  • -execdir将所有内容运行到包含匹配文件的目录中的;字符
  • $SHELL -c使用-c参数运行您的$ SHELL(例如/ bin / bash),该参数立即执行其各自的值,而不是创建您可以输入的交互式shell
      由于"grep -v '$keyword' {} >newClassFile.trans"
    • -execdir在文件的相应目录中运行grep并输出重定向;请注意,查找将{}转换为匹配文件的名称
    • 这是必要的,因此>重定向在子命令中运行,而不是在“当前”shell中运行find命令
  • \;转义;字符,以便可以发送它而不是充当命令终结符

测试:

# Set up the folders and test files
$ mkdir -p main_folder/{f1,f2,f3}
$ for i in main_folder/f?; do printf 'a\nb\nc\n' >$i/classFile.trans; done

# Contents of one of the test files
$ cat main_folder/f1/classFile.trans
a
b
c

# Set the keyword to the letter 'b'
$ keyword=b

$ find ./main_folder -name classFile.trans -execdir $SHELL -c "grep -v '$keyword' {} >newClassFile.trans" \;

# newClassFile.trans was created sans 'b'
$ cat main_folder/f1/newClassFile.trans
a
c