0

我的目录具有以下结构(在 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
4

3 回答 3

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
于 2013-10-07T19:12:27.777 回答
1

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

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

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

分解各种论点:

  • -name classFile.trans搜索所有名为classFile.trans
  • -execdir运行所有内容,直到包含匹配文件的目录中;的字符
  • $SHELL -c使用立即执行其各自值的参数运行您的 $SHELL(例如 /bin/bash),-c而不是创建您可以输入的交互式 shell
    • "grep -v '$keyword' {} >newClassFile.trans"由于-execdir;在文件的相应目录中运行您的 grep 和输出重定向 请注意 find 变成{}匹配文件的名称
    • 这是必要的,因此>重定向在子命令中运行,而不是在“当前”shell 中运行 find 命令
  • \;对字符进行转义,;以便将其发送到 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
于 2013-10-07T23:39:36.660 回答
1

我会用

#!/bin/bash
for file in `find ./main_folder/ -name "classFile.trans" `; do 
   newFile=`dirname $file`/newClassFile.trans; 
   grep -v "keyword" $file > $newFile
done
于 2013-10-07T19:19:52.187 回答