简体   繁体   中英

How to add multiple lines to the beginning of many files in linux?

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

With bash:

for file in $(find . -name "*.customfile"); do
  echo Processing $file

  cat beginning.txt $file > $file.modified

  mv $file.modified $file

done

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

这是让你入门的东西,你只需要根据自己的喜好进行调整:

for i in *.customfile; do  sed -i '1s/^/<your_text> \n/' $i; done

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

You have two basic problems:

  1. Find all the files to change ( *.customfile )
  2. Add the lines to the beginning of the existing file

#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

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 (eg 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...

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

Please replace the double backticks with normal ones, I don't know how to show normal backticks here.

If you don't want the file prepend.txt you can replace the cat-command with lines with a "\\n" after the text.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM