2

I have a file abc.txt in the folder /etc/zyz/ and also in a few sub folders /etc/zyz-1/ /etc/zyz-2/

How can I modify all of those files with a echo command for example (all named abc.txt) in every folder that starts with /etc/zyz? In some machines there are only two folders, in other there are 10+

Example of commands I want to run

echo 'New line data' >> abc.txt

abc.txt < /dev/null
  • With what echo command? What do you want to do to the files? – terdon Jul 26 '15 at 21:03
  • I have added the two commands I want to use above. – Teddy291 Jul 26 '15 at 21:07
  • The second command doesn't do anything. Well, it will give an error but nothing apart from that. What do you want it to do? – terdon Jul 26 '15 at 21:12
  • It should empty abc.txt – Teddy291 Jul 26 '15 at 21:17
  • 2
    Um, no. That would be > abc.txt. In any case, why would you go to the trouble of writing something to a file only to immediately delete it? – terdon Jul 26 '15 at 21:18
2

Given the following tree (empty abc.txt):

.
├── zyz
│   └── abc.txt
├── zyz-1
│   └── abc.txt
└── zyz-2
    └── abc.txt

You can list all the abc files with:

$ echo zyz*/abc.txt
  zyz-1/abc.txt zyz-2/abc.txt zyz/abc.txt

And you can use tee -a to append some input stream to all of those files at the same time:

$ echo 'New line data' | tee -a zyz*/abc.txt
  New line data

If you do it twice, each abc.txt will contain two lines:

$ cat zyz/abc.txt
  New line data
  New line data
$ cat zyz-1/abc.txt
  New line data
  New line data
$ # ...

To empty them, you can do:

$ </dev/null tee zyz*/abc.txt

or

$ : | tee zyz*/abc.txt

(You shouldn't hit the ARG_MAX limit with only a few files with short names, but with a large number of files I'd use find -exec in the + form (see the manpage).)

  • That was a typo. It should have been | rather than >. – PSkocik Jul 27 '15 at 1:07
2

There are two common approaches for this: find and shell globbing.

  1. find has an -exec option which lets you specify an action to be performed on each of its results. It makes each of find's results available as {} and you can modify them as you wish. It's slightly more complicated when you want to give arguments (such as echo foo > file). For that, you need to tell find's exec to run a shell. So, to echo foo into each of the files found, you would run:

    find /etc/ -name abc.txt -path "/etc/zyz*" \
        -exec bash -c "echo 'New line data' >> {}" \;
    
  2. Shell globbing. Certain shells (bash, zsh and ksh off the top of my head, but I'm sure there are more) can deal with recursive globbing. In bash, this is activated by shopt globstar. So, to echo New line data into each of the files, you would run:

    shopt globstar
    for f in /etc/zyz*/**/abc.txt; do echo "New line data" >> "$f"; done
    

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.