3.3.2.6 Interspersing File Names

xargs can insert the name of the file it is processing between arguments you give for the command. Unless you also give options to limit the command size (see Limiting Command Size), this mode of operation is equivalent to ‘find -exec’ (see Single File).

-I replace-str
--replace[=replace-str]
-i[replace-str]

Replace occurrences of replace-str in the initial arguments with names read from standard input. Also, unquoted blanks do not terminate arguments; instead, the input is split at newlines only. If replace-str is omitted (omitting it is allowed only for ‘-i’ and ‘--replace’), it defaults to ‘{}’ (like for ‘find -exec’). Implies ‘-x’ and ‘-L 1’. The ‘-i’ option is deprecated in favour of the ‘-I’ option.

As an example, to sort each file in the bills directory, leaving the output in that file name with .sorted appended, you could do:

find bills -type f | xargs -I XX sort -o XX.sorted XX

The equivalent command using ‘find -execdir’ is:

find bills -type f -execdir sort -o '{}.sorted' '{}' ';'

When you use the ‘-I’ option, each line read from the input is buffered internally. This means that there is an upper limit on the length of input line that xargs will accept when used with the ‘-I’ option. To work around this limitation, you can use the ‘-s’ option to increase the amount of buffer space that xargs uses, and you can also use an extra invocation of xargs to ensure that very long lines do not occur. For example:

somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}'

Here, the first invocation of xargs has no input line length limit because it doesn’t use the ‘-I’ option. The second invocation of xargs does have such a limit, but we have ensured that it never encounters a line which is longer than it can handle.

This is not an ideal solution. Instead, the ‘-I’ option should not impose a line length limit (apart from any limit imposed by the operating system) and so one might consider this limitation to be a bug. A better solution would be to allow xargs -I to automatically move to a larger value for the ‘-s’ option when this is needed.

This sort of problem doesn’t occur with the output of find because it emits just one filename per line.