尝试将多个文件合并为一个时,cat“输入文件是输出文件”

尝试将多个文件合并为一个时,cat“输入文件是输出文件”

该计划是将 Java 的所有源代码行递归地收集到一个文件中:

$ find . -name '*.java' | xargs cat >> all.java

但是有一个错误:

cat: ./all.java: input file is output file

该文件all.java在执行此命令之前不存在,所以我认为可能xargs正在尝试运行cat >> all.java file1 file2 file3 ...

答案1

首先,您可以放心地忽略该错误。该命令将成功运行,并且它将正确地忽略all.java自身。它只是让您知道它这样做了。

无论如何,为了避免错误,您可以使用teefind's执行选项:

$ find . -name '*.java' -exec cat {} + | tee all.java

man find

   -exec command ;
          Execute  command;  true  if 0 status is returned.  All following
          arguments to find are taken to be arguments to the command until
          an  argument  consisting of `;' is encountered.  The string `{}'
          is replaced by the current file name being processed  everywhere
          it occurs in the arguments to the command, not just in arguments
          where it is alone, as in some versions of find. 

   -exec command {} +
          This  variant  of the -exec action runs the specified command on
          the selected files, but the command line is built  by  appending
          each  selected file name at the end; the total number of invoca‐
          tions of the command will  be  much  less  than  the  number  of
          matched  files. 

因此,您可以使用-exec来告诉find对每个结果运行命令。 被{}替换为找到的实际文件/目录名称。只是告诉命令在这里结束的+标记。我使用它而不是因为它将运行更少的命令,因为它将尝试将它们组合成尽可能少的运行。find\;

或者使用 find!来排除all.java

$ find . -name '*.java' ! -name all.java -exec cat {} +  >> all.java

或者通配符

$ shopt -s globstar
$ cat **/*.java > all.java

答案2

问题是第一的该文件all.java已创建,然后find找到它并将其输入到cat,但它不喜欢它,因为它在那里输出。

可能的解决方案:

$ find . -name '*.java' | xargs cat >> all.j

或者:

$ find . -name '*.java' | xargs cat >> ../all.java

相关内容