Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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'
share|improve this question
add comment

3 Answers 3

up vote 6 down vote accepted
find . -name TheFileName -type f -exec sh -c 'for i do
     echo SomeText > "$i"; done' sh {} +
share|improve this answer
    
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 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 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 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 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 at 8:41
add comment

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).

share|improve this answer
    
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 at 10:14
add comment

A little bit shorter:

find . -name TheFileName -type f -exec sed -n -i -e '1c SomeText' {} +
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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