4

План состоял в том, чтобы собрать все исходные строки 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 ...

2 ответа2

6

Прежде всего, вы можете смело игнорировать эту ошибку. Команда будет выполнена успешно и будет игнорировать сам all.java . Это просто дать вам знать, что это так.

В любом случае, чтобы избежать ошибки, вы можете использовать команду tee и find's exec:

$ 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's ! исключить все all.java:

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

Или шарить:

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

Проблема заключалась в том, что сначала был создан файл all.java , затем find нашла его и передала его cat , которому он не понравился, потому что он выводил его туда.

Возможное решение:

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

Или же:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .