The most straight forward way I can see to do this is with GNU find
, bash
and the sponge
utility from moreutils:
find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -print0 |
while IFS= read -rd '' file; do
echo 'cat path/to/theCommonComment.txt "$file" | sponge "$file"'
done
As it stands this will just print the cat
/sponge
commands without actually doing anything. Once you are sure you have what you want, you can remove the echo and the single quotes surrounding the command.
Without using sponge
or the -print0
option for find which may not be available on all systems:
find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -exec sh '
for file; do
tempfile=$(mktemp)
cat path/to/theCommonComment.txt "$file" >"$tempfile"
mv "$tempfile" "$file"
done
' sh {} +
There is no easy way to stop this one simply print what it will do, so be careful. One thing to watch out for - make sure your theCommonComment.txt
file is not in the directory you are doing the recursive operation in (or at least make sure that it is excluded from the find), or else you will end up with two of the headers in some files.
Update
A final thought is that you may want to check if the header has already been added to the file. This may be useful if you add new files and have to run the command again. It also gets around the problem of having the theCommonComment.txt
file in the search path. The two solutions would become:
comment_file=path/to/theCommonComment.txt
size=$(wc -c "$comment_file")
find dir/with/files -name '.txt' ! -name '.DontTouch.txt' -print0 |
while IFS= read -rd '' file; do
if [ cmp -n "$size" $comment_file" "$file" ]; do
echo 'cat "$comment_file" "$file" | sponge "$file"'
fi
done
export comment_file=path/to/theCommonComment.txt
export size=$(wc -c "$comment_file")
find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -exec sh '
for file; do
if [ cmp -n "$size" $comment_file" "$file" ]; do
tempfile=$(mktemp)
cat "$comment_file" "$file" >"$tempfile"
mv "$tempfile" "$file"
fi
done
' sh {} +