Home > OS >  Xargs append string to files
Xargs append string to files

Time:05-31

I have multiple text files in a directory. At the end I want to append a string.

Eg. List of text files in directory.

  • a.txt
  • b.txt
  • c.txt

Command to get their path:

find -name "*txt"

Then I tried to send

'echo "example text" > <filename>

So I tried running the following:

find -name "*txt" | xargs echo "example_text" >>

This command fails.

All I want to is append some text to the files every now and then and since the names of the files keep changing I wanted to use xargs

CodePudding user response:

xargs isn't really appropriate here. Maybe a loop over filenames like

for file in *.txt; do
    echo "example_text" >>"$file"
done

CodePudding user response:

Because >> is a shell directive, if you want it honored via xargs, you need to have xargs start a shell. As Shawn's answer demonstrates, in many cases a shell glob is enough and you don't need find at all; but if you do want to use find, it can be used correctly either with or without xargs.


If you insist on using xargs, even though it isn't the best tool for the job...

find -name "*.txt" -print0 | xargs -0 sh -c '
  for arg in "$@"; do echo "example_text" >>"$arg"; done
' _

Taking xargs out, and just using find (with -exec ... {} to get the same performance benefits xargs would otherwise offer):

find -name "*.txt" -exec sh -c '
  for arg in "$@"; do echo "example_text" >>"$arg"; done
' _ {}  

(in both of the above, the _ substitutes for $0, so later arguments become $1 and later, and are thus iterated over when expanding "$@").

CodePudding user response:

As many pointed out, xargs is not appropriate, so you could just simply use find and pipe to read in a loop to accomplish what you want easily as shown below.

find . -name "*.txt" | while read fname; do echo "example_text">>$fname; done

CodePudding user response:

From the point of view of bash, there are three parts in your command:

  • Before the pipe character (find -name "*txt")
  • Between the pipe and the redirection (xargs echo "example_text")
  • After the redirection ( )

bash tries to open the output file provided after the redirection but, as you didn't provided anything, bash cannot open "nothing" and fails.

To solve your issue, you need to give xargs a way to add the line you need to the file (without asking bash to redirect the output of xargs). A way that should work could be by starting a subshell that performs that operation:

find -name "*txt" | xargs -I{} bash -c 'echo "example_text" >> {}'
  • Related