Operating System - Linux
1830227 Members
2658 Online
109999 Solutions
New Discussion

Challenging Script question

 
SOLVED
Go to solution
Unix or Linux?
Frequent Advisor

Challenging Script question

I have a file named File1 with the following data:
Line1
Line2
Line3
Line4
Line5

Im trying to write a script that takes two arguments. The first being a line of text and the second the name of the file above. How do I insert the first argument(line of text) into the first line of the file named above.

For example:

./scriptTest Hello this is a test File1

Would append File1 as such:
Hello this is a test
Line1
Line2
Line3
Line4
Line5
37 REPLIES 37
Mel Burslan
Honored Contributor

Re: Challenging Script question

header=$1
filename=$2
(echo $header ;cat $filename) > /tmp/mytmpfile
mv /tmp/mytmpfile $filename


one of the ways how to do it..

HTH
________________________________
UNIX because I majored in cryptology...
Mel Burslan
Honored Contributor

Re: Challenging Script question

forgot to add, if your comment is multiple words containing spaces, make sure to enclose it in quotes.
________________________________
UNIX because I majored in cryptology...
Pete Randall
Outstanding Contributor

Re: Challenging Script question

You're going to have to put quotes around the "Hello this is a test", then your script will look like:

echo $1 > /tmp/file
cat $2 >> /tmp/file
cp /tmp/file $2


Pete


Pete
James R. Ferguson
Acclaimed Contributor

Re: Challenging Script question

Hi:

Using the shell only:

cat ./insertit
#!/usr/bin/sh
echo "${1}" >> "${2}.new"
cat ${2} >> "${2}.new"
mv "${2}.new" "${2}"

# ./insert it ok yourfile

Regards!

...JRF...
Unix or Linux?
Frequent Advisor

Re: Challenging Script question

Hi is there any other way to do it without having to use quotes. I cant say to the user if you have more than one word then put quotes around it.

So far I have managed the following.

sed -e '1i\' -e "$*" > File1

But this appends the whole line including the second argument.
Rodney Hills
Honored Contributor

Re: Challenging Script question

Can you have the users put the filename first, then-

f=$1
t=/tmp/hold$$
shift
echo $* | cat - $f >$t
mv $t $f

HTH

-- Rod Hills
There be dragons...
Sandman!
Honored Contributor

Re: Challenging Script question

How about the following:

echo hello this is a test file1 | awk '{
for(i=1;i $NF
}'

cheers!
Unix or Linux?
Frequent Advisor

Re: Challenging Script question

Hi

The line of text has to come first then the file name.

Thank you
Unix or Linux?
Frequent Advisor

Re: Challenging Script question

Hi Sandman


Im not sure that will work. How does the script know to echo the line of text: Hello this is a test, unless you manually type it in the script.

It could be any line of text.
Sandman!
Honored Contributor

Re: Challenging Script question

Infact to build a shell script do the following:

=================myshellscript=================
#!/bin/sh

echo $* | awk '{
for(i=1;i $NF
}'
=============================================

Give your script a name "myshellscript" make it executable "chmod" and execute it at the command line as...

# ./myshellscript

hope it helps!
Kent Ostby
Honored Contributor

Re: Challenging Script question

You can do it without quotes like this:

given file1
Line1
Line2
Line3
Line4
Line5

./script Hello world file1

script:
touch .mytempx
rm .mytemp?*
echo $@ | awk '{print "cp ", $NF, " .mytempfile2" }' > .mytempx
echo $@ | awk '{print "cat ", " .mytempfile2 >> .mytempfile3"; print " mv .mytempfile3 ",$NF }' > .mytempx2
chmod +x .mytempx .mytempx2
./.mytempx
echo $@ | awk '{$1==$NF="";print $0}' > .mytempfile3
./.mytempx2

"Well, actually, she is a rocket scientist" -- Steve Martin in "Roxanne"
Sandman!
Honored Contributor

Re: Challenging Script question

In my last post I forgot to add that run the shell script you created as follows:

# myshellscript Hello this is a test file1

...passing command line arguments to the script instead of running it w/o any.

cheers!
James R. Ferguson
Acclaimed Contributor

Re: Challenging Script question

Hi:

Here's yet another way to offer the user the ability to specify the name of the file *last* and the string to insert *first* without the need to quote anything:

# cat .inject.pl
#!/usr/bin/perl
my $file = pop;
open(FH,"<",$file) or die "Can't open $file\n";
print "@ARGV\n";
print while ();
1;

For example:

# ./inject.pl Hello this is a test FileName

Regards!

...JRF...
Rodney Hills
Honored Contributor

Re: Challenging Script question

Here is a method that uses ksh arrays to pick off the last argument.

set -A a $*
(( n = ${#a[*]} - 1 ))
f=${a[$n]}
a[$n]=""
t=/tmp/hold$$
echo ${a[*]} | cat - $f >$t
mv $t $f

HTH

-- Rod Hills
There be dragons...
Unix or Linux?
Frequent Advisor

Re: Challenging Script question

Hi Sandman

Just tried your code but it seems to delete everything in the file and then write the line of text to the file.

Any ideas?
James R. Ferguson
Acclaimed Contributor

Re: Challenging Script question

Hi:

If you prefer not to preserve your original file, but use the Perl script I suggested, then use this version:

# cat .inject.pl
#!/usr/bin/perl
my $oldfile = pop;
my $newfile = "$oldfile.new";
open(FIN, "<",$oldfile) or die "Can't open '$oldfile': $!\n";
open(FOUT,">",$newfile) or die "Can't open '$newfile': $!\n";
print FOUT "@ARGV\n";
print FOUT while ();
close FOUT;
close FIN;
rename($newfile, $oldfile);
1;

For example:

# ./inject.pl Hello this is a test FileName

In this variation, the modified file ("FileName") is updated, "in-place".

Regards!

...JRF...
Sandman!
Honored Contributor
Solution

Re: Challenging Script question

>Just tried your code but it seems to delete >everything in the file and then write the >line of text to the file.

>Any ideas?

Here's the updated version of "myshellscript" so that file1 doesn't get clobbered and the text gets written above the first line in file1:

=============================================
#!/bin/sh -x

echo $@ | awk '{
system("mv "$NF" tmpfile1")
for(i=1;i $NF
system("cat tmpfile1 >>"$NF)
}'
=============================================

hope it helps!
Unix or Linux?
Frequent Advisor

Re: Challenging Script question

Hi Sandman

It worked perfectly. Thank you.
Any chance that you could explain the code as it is a bit advanced for me.
Sandman!
Honored Contributor

Re: Challenging Script question

The shell script is attached so that its clearer to follow. Moreover you can use $* and $@ interchangeably.

cheers!
Unix or Linux?
Frequent Advisor

Re: Challenging Script question

Thank you

How much of the code would need to be modified if I wanted to insert the line in the middle of the file?
Sandman!
Honored Contributor

Re: Challenging Script question

Explanation:

#!/bin/sh

echo $* | awk '{
system("mv "$NF" tmpfile1")
for(i=1;i $NF
system("cat tmpfile1 >>"$NF)
}'

The command line arguments are echoed and piped to the awk where they are split into different fields, NF being the last one and in this case it's the filename.

The system command renames (mv) file1 to tmpfile1; printf writes all the fields except the last one to file1; and finally the contents of tmpfile1 are appended (cat) to file1.

hope it makes sense
:)
Sandman!
Honored Contributor

Re: Challenging Script question

Thank you

How much of the code would need to be modified if I wanted to insert the line in the middle of the file?

If you knew where exactly you need to add the "Hello this is a test" for example say it was before line4; then split file1 into two files (say f1 and f2); run the awkscript; and concatenate f1 file1 f2 together to produce the desired result as folows:

#!/bin/sh

echo $* | awk '{
system("split -l 3 "$NF)
for(i=1;i "tmpfile1"
system("cat xaa tmpfile1 xab >"$NF)
}'

Sandman!
Honored Contributor

Re: Challenging Script question

>Thank you

>How much of the code would need to be modified if I wanted to insert the line
>in the middle of the file?

If you knew where exactly you need to add the "Hello this is a test" for example say it was before line4; then split file1 into two files (say f1 and f2); run the awkscript; and concatenate f1 file1 f2 together to produce the desired result as folows:

#!/bin/sh

echo $* | awk '{
system("split -l 3 "$NF)
for(i=1;i "tmpfile1"
system("cat xaa tmpfile1 xab >"$NF)
}'

Unix or Linux?
Frequent Advisor

Re: Challenging Script question

Hi Sandman

How can you insert a line exactly in the middle of the file.
I have tried the following but it doesnt work. Any ideas?

#!/bin/sh

COUNT=`cat $NF | wc -l`
COUNT=`expr $COUNT \ 2`
echo $* | awk '{
system("split -l $COUNT "$NF)
for(i=1;i "tmpfile1"
system("cat xaa tmpfile1 xab >"$NF)
}'