I need to fill all files with a specific filename (recursively) with a text. In zsh this can be done with

echo SomeText > **/TheFileName

I search generic solutions for sh-compatible and/or tcsh shells. Is there a shorter/easier way than the following command?

find . -name "TheFileName" -print0 | xargs -0 sed -n -i -e '1c\nSomeText'
find . -name TheFileName -type f -exec sh -c 'for i do
     echo SomeText > "$i"; done' sh {} +
  • Would you mind explain me what the last sh is for? I don't understand why the first sh -c is not sufficient. – lgeorget Jun 16 '14 at 6:36
  • 1
    @mikeserv With $1, only the first listed file gets written to. Do you think it's only true for my shell (zsh) and my implementation of find (the GNU one)? Thank you for your answer. – lgeorget Jun 16 '14 at 7:18
  • 1
    @mikeserv I confirm that my find doesn't go in the correct file's directory. And that would be strange because the point of the + is to launch the command only once with all the files as parameters. So, how could the command be in the right directory for each one? – lgeorget Jun 16 '14 at 7:26
  • So @StephaneChazelas, you meant either for i do echo SomeText > "$i"; done or for i do echo SomeText > "$1"; shift; done, right? – lgeorget Jun 16 '14 at 7:38
  • 2
    @lgeorget, yes, that was a typo, thanks for the edit. As mikeserv said, the second sh is for the inline-script's $0 (used for error messages for instance). – Stéphane Chazelas Jun 16 '14 at 8:41

You can use tee for this:

If your shell properly matches the **/TheFileName, and the issue is simply getting the content in each file:

echo SomeText | tee **/TheFileName >/dev/null

If the issue is that **/TheFileName isn't matching properly, you can use find:

echo SomeText | find . -name TheFileName -exec tee {} + >/dev/null

If your find doesn't have -exec +, then the other solutions here are appropriate.

These also won't work if you have a very large number of files (greater than getconf ARG_MAX).

  • The limit on the number of concurrently open files is likely to be reached before that of ARG_MAX though. – Stéphane Chazelas Jun 20 '14 at 10:14

A little bit shorter:

find . -name TheFileName -type f -exec sed -n -i -e '1c SomeText' {} +

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.