使用find和cat来复制多个文件的内容



Dears,

我已经尝试了";查找";以及";猫;在bash脚本中复制子目录中数百个文件的内容:

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 >> "{}"' ;

然而,该命令并没有给我想要的结果。我预计;U〃;通过find找到;temp";将被覆盖。但我看到之前发现的";U〃;s被附加到";temp";,积累其内容。如果我试图删除";temp";使用以下方法:

-exec rm -rf temp ;

然后我会收到一个错误:

cat:temp:没有这样的文件或目录

为了简单起见,我省略了一些其他-exec选项。

有人能说出我可能错在哪里吗?我很感激任何提示。

致以亲切的问候。

您希望-execdir而不是-exec在与U相同的目录中创建临时文件。重定向应该在bash会话中:事实上,所有shell操作都可以在同一个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

echofoo视为其参数,并将其发送到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 >> "{}"' ;

最新更新