问题
I want to insert multiple lines into a file using shell script. Let us consider my input file contents are: input.txt:
abcd
accd
cdef
line
web
Now I have to insert four lines after the line 'cdef' in the input.txt file. After inserting my file should change like this:
abcd
accd
cdef
line1
line2
line3
line4
line
web
The above insertion I should do using the shell script. Can any one help me?
回答1:
Another sed,
sed '/cdef/r add.txt' input.txt
input.txt:
abcd
accd
cdef
line
web
add.txt:
line1
line2
line3
line4
Test:
sat:~# sed '/cdef/r add.txt' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web
If you want to apply the changes in input.txt file. Then, use -i with sed.
sed -i '/cdef/r add.txt' input.txt
If you want to use a regex as an expression you have to use the -E tag with sed.
sed -E '/RegexPattern/r add.txt' input.txt
回答2:
Using GNU sed:
sed "/cdef/aline1\nline2\nline3\nline4" input.txt
If you started with:
abcd
accd
cdef
line
web
this would produce:
abcd
accd
cdef
line1
line2
line3
line4
line
web
If you want to save the changes to the file in-place, say:
sed -i "/cdef/aline1\nline2\nline3\nline4" input.txt
回答3:
sed '/^cdef$/r'<(
echo "line1"
echo "line2"
echo "line3"
echo "line4"
) -i -- input.txt
回答4:
Using awk:
awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt
Explanation:
- You find the line you want to insert from using
/.../ - You print the current line using
print $0 RSis built-inawkvariable that is by default set tonew-line.- You add new lines separated by this variable
1at the end results in printing of every other lines. Usingnextbefore it allows us to prevent the current line since you have already printed it usingprint $0.
$ awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web
To make changes to the file you can do:
awk '...' input.txt > tmp && mv tmp input.txt
回答5:
This answer is easy to understand
- Copy before the pattern
- Add your lines
- Copy after the pattern
Replace original file
FILENAME='app/Providers/AuthServiceProvider.php'
STEP 1 copy until the pattern
sed '/THEPATTERNYOUARELOOKINGFOR/Q' $FILENAME >>${FILENAME}_temp
STEP 2 add your lines
cat << 'EOL' >> ${FILENAME}_temp
HERE YOU COPY AND
PASTE MULTIPLE
LINES, ALSO YOU CAN
//WRITE COMMENTS
AND NEW LINES
AND SPECIAL CHARS LIKE $THISONE
EOL
STEP 3 add the rest of the file
grep -A 9999 'THEPATTERNYOUARELOOKINGFOR' $FILENAME >>${FILENAME}_temp
REPLACE original file
mv ${FILENAME}_temp $FILENAME
if you need variables, in step 2 replace 'EOL' with EOL
cat << EOL >> ${FILENAME}_temp
this variable will expand: $variable1
EOL
回答6:
I needed to template a few files with minimal tooling and for me the issue with above sed -e '/../r file.txt is that it only appends the file after it prints out the rest of the match, it doesn't replace it.
This doesn't do it (all matches are replaced and pattern matching continues from same point)
#!/bin/bash
TEMPDIR=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")
# remove on exit
trap "rm -rf $TEMPDIR" EXIT
DCTEMPLATE=$TEMPDIR/dctemplate.txt
DCTEMPFILE=$TEMPDIR/dctempfile.txt
# template that will replace
printf "0replacement
1${SHELL} data
2anotherlinenoEOL" > $DCTEMPLATE
# test data
echo -e "xxy \n987 \nxx xx\n yz yxxyy" > $DCTEMPFILE
# print original for debug
echo "---8<--- $DCTEMPFILE"
cat $DCTEMPFILE
echo "---8<--- $DCTEMPLATE"
cat $DCTEMPLATE
echo "---8<---"
# replace 'xx' -> contents of $DCTEMPFILE
perl -e "our \$fname = '${DCTEMPLATE}';" -pe 's/xx/`cat $fname`/eg' ${DCTEMPFILE}
回答7:
You can use awk for inserting output of some command in the middle of input.txt.
The lines to be inserted can be the output of a cat otherfile, ls -l or 4 lines with a number generated by printf.
awk 'NR==FNR {a[NR]=$0;next}
{print}
/cdef/ {for (i=1; i <= length(a); i++) { print a[i] }}'
<(printf "%s\n" line{1..4}) input.txt
来源:https://stackoverflow.com/questions/22497246/insert-multiple-lines-into-a-file-after-specified-pattern-using-shell-script