Reputation: 95
I have a file with the following contents
script.sh
#!/bin/bash
.... some commands
cat << 'EOF1' > scriptfile1.sh
file1 command1
file1 command2
file1 command3
EOF1
.... some commands
cat << 'EOF2' > scriptfile2.sh
file2 command1
file2 command2
file2 command3
EOF2
.... some commands
and I have the following files
file1.sh
new command1 for file1
new command2 for file1
new command3 for file1
file2.sh
new command1 for file2
new command2 for file2
new command3 for file2
I want from file script.sh to find the part of text that starts with "cat << 'EOF1' > file1.sh" and ends with "EOF1" and then replaced with the content of file1.sh and so on ....
And after that my output of script.sh to be like that
#!/bin/bash
.... some commands
cat << 'EOF1' > scriptfile1.sh
new command1 for file1
new command2 for file1
new command3 for file1
EOF1
.... some commands
cat << 'EOF2' > scriptfile2.sh
new command1 for file2
new command2 for file2
new command3 for file2
EOF2
.... some commands
I have found the following but I can't make it work
Replace block of text inside a file using the contents of another file using sed
How can I do it preferably with the awk
Upvotes: 1
Views: 1231
Reputation: 203169
In this case where you can generate the names of the files to be read as you go, I'd do the following (using any awk in any shell on every Unix box):
$ cat tst.awk
$0 == hereEnd {
hereEnd = ""
}
hereEnd == "" {
print
if ( /^cat <</ ) {
gsub(/["\047]/," ")
hereEnd = $3
file = "file" (++hereCnt) ".sh"
while ( (getline line < file) > 0 ) {
print line
}
}
}
$ awk -f tst.awk script.sh
#!/bin/bash
.... some commands
cat << 'EOF1' > scriptfile1.sh
new command1 for file1
new command2 for file1
new command3 for file1
EOF1
.... some commands
cat << 'EOF2' > scriptfile2.sh
new command1 for file2
new command2 for file2
new command3 for file2
EOF2
.... some commands
See http://awk.freeshell.org/AllAboutGetline for caveats of using getline
.
Alternatively you could read each of the intermediate files specified on the command line into memory, e.g. with GNU awk for ARGIND
:
$ cat tst.awk
ARGIND < (ARGC-1) {
file[ARGIND] = (FNR>1 ? file[ARGIND] ORS : "") $0
next
}
$0 == hereEnd {
hereEnd = ""
}
hereEnd == "" {
print
if ( /^cat <</ ) {
gsub(/["\047]/," ")
hereEnd = $3
print file[++hereCnt]
}
}
$ awk -f tst.awk file{1..2}.sh script.sh
#!/bin/bash
.... some commands
cat << 'EOF1' > scriptfile1.sh
new command1 for file1
new command2 for file1
new command3 for file1
EOF1
.... some commands
cat << 'EOF2' > scriptfile2.sh
new command1 for file2
new command2 for file2
new command3 for file2
EOF2
.... some commands
If you don't have GNU awk you can do the same by just adding FNR==1 { ARGIND++ }
at the start of the script.
The above assumes you have at least as many fileN.sh
files as you have here documents in script.sh
. With the above you don't need to have separate EOF1
, EOF2
, delimiters for each here doc, they could all just use EOF
or any other symbol.
Upvotes: 1
Reputation: 784928
You may use this sed
:
cat subs.sed
/^cat << 'EOF1'.*/,/^EOF1$/ {
//!d
/^cat /r file1.sh
}
/^cat << 'EOF2'.*/,/^EOF2$/ {
//!d
/^cat /r file2.sh
}
# use it as:
sed -f subs.sed script.sh
#!/bin/bash
.... some commands
cat << 'EOF1' > scriptfile1.sh
new command1 for file1
new command2 for file1
new command3 for file1
EOF1
.... some commands
cat << 'EOF2' > scriptfile2.sh
new command1 for file2
new command2 for file2
new command3 for file2
EOF2
.... some commands
Upvotes: 1