递归查找所有名为“file.txt”的文件并执行sed命令

递归查找所有名为“file.txt”的文件并执行sed命令

我的任务的挑战是可以file.txt位于子文件夹或子子文件夹中。一般结构如下:

   folder
     |___subfolder
             |_____file.txt
     |
     |___subfolder
             |____subfolder
                      |_______file.txt
     etc

我之前的代码不处理子子文件夹,我不知道如何添加这部分(因为某些子文件夹没有任何后续文件夹)

 for dir in ./*/ ; do
        if [ -d "$dir" ]; then 
           cd $d;
           for subdir in ./*/; do
               cd $subdir && $(sed command file.txt) && cd ..;
           done
           cd ..
        fi
done

我还了解到有一种使用的单行方法find,例如:

find . -name 'file.txt' | sed command file.txt

显然这个不起作用,因为find只能将目录返回到我的file.txt

答案1

尝试:

find . -name 'file.txt' -exec sed command {} +

file.txt这将查找子目录中名为该文件的所有文件,并针对这些文件.运行。sed command

如果您想sed就地修改这些文件,请添加该-i选项。

虽然-exec ... +现在需要POSIX(提示:jordanm),有些人可能正在使用find不支持+.如果您有其中之一,请使用(帽子提示:unxnut):

find . -name 'file.txt' -exec sed command {} \;

更安全的选择

如果对目录结构进行快速更改,-exec则可能会出现竞争条件。为了提高安全性,请使用-execdir(帽子提示:unxnut):

find . -name 'file.txt' -execdir sed command {} +

请注意,如果您的 中有当前目录PATH-execdir则将拒绝运行。

答案2

除非您知道该sed命令在做什么,否则您希望sed每个输入文件运行一个命令。
您可以使用for循环来完成此操作(如果您的 shell 支持递归通配符),例如zshksh93yashbashtcsh以及fish,但循环语法不同)。

shopt -s globstar        # bash
#set -o globstar         # ksh93
#set -o extended-glob    # yash

for f in **/file.txt; do [ -f "$f" ] && sed 'cmd' "$f"; done

或(正如其他人指出的)find

find . -type f -name 'file.txt' -exec sed 'cmd' {} \;

现在,有人可能想知道 - 为什么不“优化”这一点并将finds-exec+ 或 a zsh-ism 一起使用,例如:

sed 'cmd' **/file.txt(.)

当然,这些会更有效,因为它们调用sed多个文件操作数但是很可能存在问题:
为了简单起见,假设您尝试使用命令sed11q打印每个文件的第一行(不就地编辑文件2,也许将组合输出重定向到另一个文件或只是检查它)所以你可以运行

find . -name 'file.txt' -exec sed '1q' {} +

或者

sed '1q' **/file.txt(.)

然而他们都将无法交付,因为
如果指定了多个文件操作数,则应按指定的顺序读取指定的文件并编辑连接
因此,sed只会打印输入的第一行,而不是每个文件3的第一行。
现在,gnu sed-s开关:

-s, --separate
        consider files as separate rather than as a single continuous long stream

有时这可能会派上用场,但在这种特殊情况下(1q),它没有帮助。


1:如果你不喜欢1q尝试$d,应该删除每个文件的最后一行2:有时你可能会像暗示的那样
逃脱,但绝对不是当命令之一是gnu sed-i-ssedq
3:你可能会争辩说这是因为q退出 - 但是如果你使用sed -n '1p'- 我只q强调 2,也会发生同样的情况:

答案3

假设您的文件路径不包含空格、换行符、单引号、双引号或反斜杠字符:

find . -name 'file.txt' -type f | xargs sed command

相关内容