Reputation: 62634
I have a file beginning.txt that contains lines like:
Disclaimer Here
This is a Notice
I have something liere
How can I execute a linux command to add all the lines in beginning.txt to the top of each file that matches the extension ".customfile" (note that .customfile is just a textfile, but these files may be within subdirectories within my current folder that i also want updated)?
I have many files with the .customfile suffix that I want to append, so looking for a way to do this programatically. I see example with sed command that appear limited to a single line.
sed -i '1s/^/<added text> /' file
Upvotes: 8
Views: 9386
Reputation: 727
Here is another small solution without a tmp-File (Only the beginning text is in one file)
for i in `ls *.customfile`; do echo -e "`cat prepend.txt`$(cat $i)" > $i; done
If you don't want the file prepend.txt you can replace the cat-command with lines with a "\n" after the text.
Upvotes: 0
Reputation: 36793
With bash:
for file in $(find . -name "*.customfile"); do
echo Processing $file
cat beginning.txt $file > $file.modified
mv $file.modified $file
done
Upvotes: 21
Reputation: 6758
The sed
command r
is pretty useful in appending contents of a file at certain location, except when that location is line 0.
Inserting your text before line 1 is like appending after line 0. It would've been the solution if sed '0r /path/to/beginning.txt *.customfile
was allowed.
You can use process substitution along with sed
. The process substitution will generate a sed
command that can be run against any files you searched for.
sed -i -f - file < <(sed 's/^/1i/' /path/to/beginning.txt)
The process sed 's/^/1i/' /path/to/beginning.txt
will generate sed
commands to insert the texts found in /path/to/beginning.txt
:
1iDisclaimer Here
1iThis is a Notice
1iI have something liere
sed -f -
will read the sed command from a file, -
means the file is stdin
.
If you need to run it on multiple files, you can either use globs or find
and xargs
.
Sample using multiple files:
sed -i -f - /path/to/*.customfile < <(sed 's/^/1i/' /path/to/beginning.txt)
Sample using find and xargs:
find . -type f -name \*.customfile | xargs -I{} bash -c "sed -f - {} < <(sed 's/^/1i/' /tmp/beginning.txt)"
Alternatively, you can avoid re-running sed 's/^/1i/' /path/to/beginning.txt
for every file by assigning the output to a variable and using here string to pass to the sed
command.
sedcommand=$(sed 's/^/1i/' /path/to/beginning.txt)
sed -i -f - /path/to/*.customfile <<< "$sedcommand"
Or create a command.sed
file from beginning.txt
and use it to insert the texts to your custom files.
sed 's/^/1i/' /path/to/beginning.txt > /path/to/command.sed
sed -i -f /path/to/command.sed /path/to/*.customfile
Upvotes: 2
Reputation: 84559
While cat
is the proper shell tool for the job (see: Robert's answer, which I would suggest instead), if you do want to torment yourself with a multi-line substitution or insert of the disclaimer text at the beginning of a large number of files, you can use the Address prefix for sed
to locate the first beginning of a line, and then execute the substitution with sed
replacing the beginning of the first line (e.g. beginning of file) using the regex '^'
with your disclaimer text.
Specifically, you would be using the '0,addr2'
form of the Address for sed
where if addr2
(a regex) matches the first line of input it causes the 0,addr2
form to be at its end of range and to substitute (insert) the replacement text once and quit.
For example, to add your disclaimer at the beginning of each file in files
(whether you use globbing or find
with process-substitution to select the desired files) would take the form:
## set disclaimer text in `dc` however you like
dc='Disclaimer Here\nThis is a Notice\nI have something liere\n'
## use 0,addr2 Address form to insert at beginning of each file.
sed -i "0,/^/s/^/${dc}/" files
Example File
$ cat dat/basefile.txt
========
The quick brown fox
jumps over the lazy dog.
Example Use/Output (to stdout for example
$ dc='Disclaimer Here\nThis is a Notice\nI have something liere\n' \
sed -e "0,/^/s/^/${dc}/" dat/basefile.txt
Disclaimer Here
This is a Notice
I have something liere
========
The quick brown fox
jumps over the lazy dog.
Rather than torment yourself, use cat
instead...
Upvotes: 0
Reputation: 142
I guess you can try something like this
find . -name "*.customfile" -type f | while read i; do cat beginning.txt $i | tee $i 1>/dev/null ; done
Maybe not the most elegant use of the tee command, but it gets the job done :)
Upvotes: 0
Reputation: 1537
You have two basic problems:
*.customfile
)#1 can be solved easily with find
.
#2 is probably easiest to do by adding the lines to a temporary file, then moving files around.
Here is a one-line shell command that will do it, assuming that you have the lines you want to add in a file called beginning.txt
:
find . -name "*.customfile" -print | while read fn ; do echo fixing $fn ; cat beginning.txt "$fn" > "$fn".new && mv "$fn" "$fn".old && mv "$fn".new "$fn" ; done
Upvotes: 0
Reputation: 48
Here is something to get you started, you will just need to tweak it to your liking:
for i in *.customfile; do sed -i '1s/^/<your_text> \n/' $i; done
Upvotes: 0