如何解决使用find和cat复制多个文件的内容
亲爱的
我尝试在bash脚本中结合使用“ find”和“ cat”来复制子目录中数百个文件的内容:
find ./inlet3/* -type f -name 'U' -exec bash -c 'cat "{}"' \; > temp -exec bash -c 'cat temp >> "{}"' \;
看看给定的命令,我打算首先将每个“ U”的内容复制到一个名为“ temp”的临时文件中,该文件应该在bash脚本所在的目录中每次创建。此部分应通过以下方法实现:
-exec bash -c 'cat "{}"' \; > temp
随后应将“ temp”的内容附加到“ U”,以使文件具有重复的内容。这部分应该通过给定的方法完成:
-exec bash -c 'cat temp >> "{}"' \;
但是,命令没有给我想要的结果。我希望对于通过find找到的每个“ U”,“ temp”都将被覆盖。但是我看到先前找到的“ U”的内容被追加到“ temp”,从而累积了其内容。如果我尝试通过以下方法删除“ temp”:
-exec rm -rf temp \;
然后我会收到一个错误:
cat:temp:没有这样的文件或目录
为简单起见,我省略了其他一些-exec选项。
有人可以说我可能错了吗?我感谢任何提示。
亲切的问候。
解决方法
您希望-execdir
而不是-exec
在与U相同的目录中创建临时文件。重定向应在bash会话中进行:实际上,所有shell操作都可以在相同的外壳:
find ... -execdir sh -c 'temp=$(mktemp) && cat "{}" > "$temp" && cat "$temp" >> "{}" && rm "$temp"'
如果安装moreutils
软件包,则可以使用sponge
,而无需创建临时文件:
find ... -execdir sh -c '{ cat "{}"; cat "{}"; } | sponge "{}"'
,
我们通常说
echo foo > bar
echo
看到foo
作为参数,并将其发送到stdout,我们已将其重定向到bar
...但是不必以这种方式编写。实际上,echo
甚至都不知道其输出已被重定向。那是解析器处理流的结果,所以结果意味着您可以用一些奇怪的方式编写命令-
echo > bar foo
也可以完成,
> bar echo foo
这是违反直觉的,但还是如此。
您的命令是
find ./inlet3/* -type f -name 'U' -exec bash -c 'cat "{}"' \; > temp -exec bash -c 'cat temp >> "{}"' \;
在功能上与
相同find ./inlet3/* -type f -name 'U' -exec bash -c 'cat "{}"' \; -exec bash -c 'cat temp >> "{}"' \; > temp
或
> temp find ./inlet3/* -type f -name 'U' -exec bash -c 'cat "{}"' \; -exec bash -c 'cat temp >> "{}"' \;
因此,find
的所有输出都将进入temp
。
你想要的是
find ./inlet3/* -type f -name 'U' -exec bash -c 'cat "{} >| temp"' \; -exec bash -c 'cat temp >> "{}"' \;
除非您set -o noclobber
>
的结果在功能上与>|
相同,但是当我想要截断时,我倾向于明确。永远不会疼。
正如Glenn Jackman指出的那样,子外壳越少越好,所以-
find ./inlet3/* -type f -name 'U' -exec bash -c 'cat "{}" >| temp && cat temp >> "{}"' \;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。