I need to write to a shell script that takes a list of directories from file (the directories would be on different lines) and then for each of those filepaths it would create a hidden dummy file ( .hiddenfile for example) in each of those directories.

See, the problem I'm trying to solve is to commit empty directories into source control and we're using Git, which, ignores empty files. However, I'd like to know reuse this solution (namely, the part where a script takes a list of directories and creates or edits files in each of those directories) for other problems potentially.

The list of directories would be absolute like this: directories.txt:


The contents of the .hiddenfile would be arbitrary really. It just needs to have something so that git will commit the files like so:

# don't leave me out of source control

I'm just not sure what Unix command or to use to facilitate this.

I'm using the Mac OS X version of Unix by the way, if that matters.

Any suggestions would be greatly appreciated in advance.


Assuming your directory names are more or less sane (spaces are fine) this should work:

while read -r n; do \
   echo "# don't leave me out of source control" > "$n"/.hiddenfile; \
done < dirlist.txt

This scriptlet will iterate over the list of directories in dirlist.txt, saving each line as $n. It then uses echo to print your desired text into the file .hiddenfile in each directory.

  • Thanks, terdon! That doesn't look too hard to do. Would it help if I enclosed the directory names in double quotes on the directories.txt file? – racl101 Mar 4 '13 at 22:12
  • The backslashes and the semi-colon are unnecessary. – chepner Mar 5 '13 at 14:49
  • @chepner The semicolons are necessary when running from the command line, as are the backslashes to enable direct copy/paste. – terdon Mar 5 '13 at 15:16
  • @racl101 No it wouldn't, it would make the whole thing much harder actually. Why would you want to? Unless you have very weird dir names (containing new lines or other weird characters, the script works fine for names with spaces), the script should work. – terdon Mar 5 '13 at 15:21
  • The semicolon after .hiddenfile is only necessary if you type the whole thing on one line; a newline works just as well. The backslashes are never necessary; newlines are permitted in those places by the bash parser. – chepner Mar 5 '13 at 15:26

xargs works really well for executing a command for every argument in a list.

e.g (cygwin, OS X has xargs too):

$ find ~/tmp/ -type d | xargs.exe -Iz  echo echo $RANDOM \> "z/.hidden"   |sh
$ find ~/tmp -type f -name \.hidden |head -n4

find ~/tmp -type d can be replaced by cat /path/dirlist.txt

First part of the pipe generates a list of directories. Second part creates a command what would echo a random number (bash) and write it to a file in the found directory. Last part of the pipe executes those commands.


A "one"-liner using tee:

echo "# don't leave me out of source control" |
 tee $( while read -r; do echo "$REPLY/.hiddenfile"; done < directories.txt) \
 > /dev/null

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.