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