Operating System - Linux
1828239 Members
2512 Online
109975 Solutions
New Discussion

Re: Auto embedding one file in another

 
SOLVED
Go to solution
john guardian
Super Advisor

Auto embedding one file in another

Anyone,

Looking for a quick-n-dirty method to embed a 6 line file (script) into the middle of another file (script). I'd like some way to do this via another script as I have appx 1000+ files (scripts) that need to have these lines added.

Thanks.
11 REPLIES 11
spex
Honored Contributor
Solution

Re: Auto embedding one file in another

Hi,

You can source script2 from script1 like this:
$ . script2
or
$ source script2

PCS
James R. Ferguson
Acclaimed Contributor

Re: Auto embedding one file in another

Hi John:

Since you say "script" without further qualification, I'll asssume a shell script. In that case:

# cat /home/john/sh
#!/usr/bin/sh
X=john
. /home/john/include
Y=guardian

# cat /home/john/guardian
Z="I am!"
echo "${X} ${Y} ${Z}"

Now, when you run '/home/john/sh' the file '/home/john/include' is included "in the middle" and you get:

john guardian I am!

Note that the technique is properly called "sourcing". You use a dot (".") operator followed by a blank (space), followed by the name of the file to include.

Regards!

...JRF...

john
john guardian
Super Advisor

Re: Auto embedding one file in another

Actually, I need to get the code from script 2 into script 1... so that wouldn't be a suuficient choice...

I'm trying to eliminate as much time as possible in mod'ing 1000+ scripts IN ANY WAY...

Otherwise, I'll just create a quick script to open the 1000+ files and brute force the lines of code from script 2 into script one...

In all cases, the six lines need to be embedded into lines 2-n of all of the 1000+ scripts
Peter Godron
Honored Contributor

Re: Auto embedding one file in another

John,
you can either source the script withg . script within your first file.

Or if you want to actually include the code from file2 in file1:
sed '/regexec/r file2' file1 > new_file1
where line is the unique keyword within file1, after which you want to include the code from file2.

Example:
$ cat a2.sh
#!/usr/bin/sh
test1
this is the insert
test2
$ cat a.sh
#!/usr/bin/sh
test1
test2
$ cat b.sh
this is the insert
$ sed '/test1/r b.sh' a.sh > a2.sh
$ cat a2.sh
#!/usr/bin/sh
test1
this is the insert
test2
$

Other options of sed may give other ideas on how to position where you want the code.


Simon Hargrave
Honored Contributor

Re: Auto embedding one file in another

Assuming you want to actually add the physical lines to each file, rather than make an external call, I'd use "ed" with the "r" command to make the edit to each file. I presume you know where in the file you need to put the lines, eg after a line with a particular pattern?

An example is probably better. You have a file foo which you want to import into the middle of every file, straight after a line which reads "insert after here". Each file is called something.sh, so for example: -

for file in *.sh
do
ed $file < /insert after here/
r foo
w
q
EOF
done

You'll have to amend depending on exactly where you want the file inserting, but basically use "ed" to find the line you want, then use the "r" command to read it in, then write it out.
James R. Ferguson
Acclaimed Contributor

Re: Auto embedding one file in another

Hi (again) John:

OK, I've had coffee and read you post again, noting that:

> In all cases, the six lines need to be embedded into lines 2-n of all of the 1000+ scripts.

You can do this easily with Perl. The following script inserts a file called '/tmp/insertme' into the name of the file passed following line-2 (counting one relative). That is, immediately before line-3.

You run the filter by passing as many filenames as you need. Each file is processed, the contents of '/tmp/insertme' added to the output stream at record-2, and a new file created.

The '-i.old' switch at the top of the Perl program causes a backup copy of every file passed as an argument to be made with the extension of ".old". The modified file is left in place of the original.

# cat ./myfilter
#!/usr/bin/perl -i.old
use strict;
use warnings;
my $file = "/tmp/insertme";
open( FH, "<", "$file" ) or die "Can't open include: $!\n";
while (<>) {
if ( $. == 2 ) {
local $_;
while () {
print;
}
seek( FH, 0, 0 );
}
print;
close ARGV if eof;
}
1;

Regards!

...JRF...
spex
Honored Contributor

Re: Auto embedding one file in another

Hi John,

If you'd like the file embedded at the same line number in every .sh file in the pwd, you can give this script a shot. Call it like this:

$ ./embed-file

#!/usr/bin/sh
EMBED_FILE=$1
typeset -i POS1=$2
typeset -i POS2=$(( ${POS1} + $(wc -l ${EMBED_FILE} | awk '{print $1}') -1 ))

for FILE in $(ls *.sh)
do
sed -n "1,${POS1}p" ${FILE} > ${FILE}.tmp
cat ${EMBED_FILE} >> ${FILE}.tmp
sed -n "${POS2},\$p" ${FILE} >> ${FILE}.tmp
mv ${FILE}.tmp $FILE
done

exit 0

PCS
Sandman!
Honored Contributor

Re: Auto embedding one file in another

You can use ex(1) to embed the 6 lines into all the 1000+ scripts at lines 2-n of the target files as follows:

for FILE in $(ls -1
do
ex -s +"1 r source_file | wq" $FILE
done

The above command will loop thru each of the 1000+ files (assuming they are in a single dir) and embed the source file containing those 6 lines into each of them starting at line 2.
Sandman!
Honored Contributor

Re: Auto embedding one file in another

Typo in last post...forgot the closing parenthesis in the command substitution line. Change the for-loop to:

for FILE in $(ls -1 )
do
ex -s +"1 r source_file | wq" $FILE
done
James R. Ferguson
Acclaimed Contributor

Re: Auto embedding one file in another

Hi (again) John:

Here's a faster Perl solution than my first one. This one slurps (reads once) the file that you want to insert into your n-scripts and thus avoids repetitive I/O (although the buffer cache would probably reduce that overhead too).

As before, an automatic backup of your original file is made and the new file substitited in-place. That too, is an advantage of these Perl solutions.

# cat ./myfilter
#!/usr/bin/perl -i.old
use strict;
use warnings;
my $addendum;
{
my $file = "/tmp/insertme";
open( FH, "<", "$file" ) or die "Can't open include: $!\n";
local $/;
$addendum = ;
}
while (<>) {
print $addendum if ( $. == 3 );
print;
close ARGV if eof;
}
1;

Run this like:

# ./myfilter file1 file2 file3 ...

Backup copies will be found retained as:

file1.old, file2.old, file3.old ...

Regards!

...JRF...
john guardian
Super Advisor

Re: Auto embedding one file in another

Thanks everyone. Points assigned.