CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
unterminated `s' command

 



abhi
Novice

Mar 7, 2013, 10:17 PM

Post #1 of 7 (746 views)
unterminated `s' command Can't Post

Hi,
i am new to perl, learning it.
I wrote following script:

Code
 
#!/depot/perl-5.8.3/bin/perl

@file_list = `cat $ARGV[0]`;
@grep_list = `cat $ARGV[1]`;
$i = 0;

foreach $file_name (@file_list)
{
$g_name = @grep_list[$i];
chomp($file_name);
chomp($g_name);
`sed -i "s/$g_name/$g_name \-name \"replace NUMBER\#1234\"/g" $file_name `;
$i = $i+1;
}


fo example input file may be:
cat file1
abc/xyz/my_file
abc/pqr/other_file2

cat file2
name1
name2

When i execute this script i am getting error:
sed: -e expression #1, char 84: unterminated `s' command

I tried running "sed" from shell its working fine and replacing properly but when i put it in perl script it fails.
Please help.
Also please let me know if in perl, there is some better way of replacing word.


(This post was edited by abhi on Mar 7, 2013, 10:42 PM)


rovf
Veteran

Mar 8, 2013, 12:15 AM

Post #2 of 7 (737 views)
Re: [abhi] unterminated `s' command [In reply to] Can't Post

Backquotes (``) treat the part between them like a double quoted string, which means that the backslash (\) is seen by Perl as escape character.

You can easily see, what command is actually passed in a shell, by replacing the backquote execution by a print statement (the qq(...) form is just an alternative way for writing a double-quoted string:


Code
use strict; use warnings; 
my $g_name='xyz';
my $file_name='abcd';
print qq(sed -i "s/$g_name/$g_name \-name \"replace NUMBER\#1234\"/g" $file_name );


If you run this, you get the following output:



sed -i "s/xyz/xyz -name "replace NUMBER#1234"/g" abcd


As you can see, this is indeed a unterminated sed-command.

Three more remarks:

(1) With your usage of backquotes, you just collect the stdout of the command and throw it away immediately. In this case, it makes more sense if you redirect it to the bit bucket from the beginning:


Code
system(qq(sed .... >/dev/null));


See perldoc -f system for an explanation of the system function.

(2) It doesn't make much sense to shell out to sed for processing a file, since you can do this easily in Perl too.
There are several ways to do it, but from the code posted, it is not clear to me what you want to achieve (i.e. what you want to do with the transformed text).

(3) Please always start your program with


Code
use strict; 
use warnings;


While you are still learning Perl, I even suggest to use


Code
use strict; 
use warnings FATAL => qw(all);
use diagnostics;


instead, though I admit that not everyone would agree in this.


(This post was edited by rovf on Mar 8, 2013, 12:17 AM)


abhi
Novice

Mar 8, 2013, 12:45 AM

Post #3 of 7 (734 views)
Re: [rovf] unterminated `s' command [In reply to] Can't Post

Hi rovf,
Thanks a lot for so much or valuable info.
I will try this.

in rpl to
"it is not clear to me what you want to achieve"

Actually I want to add comments (or say more info) about name which are specified in file2

for example:
file2 contain a name "abc" and corrosponding entry in file1 say in which file "abc" present
so i want to add group id of that name (so report will generate group wise) so i will replace abc with:
abc -g_id #123

for all name mentioned in file2.
Hope this will some what clear scenario.


(This post was edited by abhi on Mar 8, 2013, 12:47 AM)


rovf
Veteran

Mar 8, 2013, 1:00 AM

Post #4 of 7 (729 views)
Re: [abhi] unterminated `s' command [In reply to] Can't Post


Quote
Actually I want to add comments (or say more info) about name which are specified in file2


So this means you want to *change* a file, and not create a new file out of an existing one? I'm asking because in your original attempt, you didn't try to attempt this either.

There are several ways to do it:

(1) Manually (open, close, rename etc.)

(2) Using the -i command line switch (most convenient, but only applicable for certain type of programs - but for you, it might work).

(3) Using Tie::File

For (1) and (2), you find a good explanation here:

http://www.perlmonks.org/?node_id=645

For (3), you get the explanation when entering

perldoc Tie::File

on the command line.


abhi
Novice

Mar 8, 2013, 1:18 AM

Post #5 of 7 (728 views)
Re: [rovf] unterminated `s' command [In reply to] Can't Post

thanks again rovf.
I will try this too.

For "So this means you want to *change* a file"
ans is "YES"

Example:
here i have 2 files:

cat file1
abc/xyz/my_file
abc/pqr/other_file2

cat file2
name1
name2

So what i need to do:
1)open file "abc/xyz/my_file"
2) replace "name1" with "name1 -g_id #123"
3)close "abc/xyz/my_file"
4)open file "abc/pqr/other_file2"
5)replace "name2" with "name2 -g_id #123"
6)close "abc/pqr/other_file2"

I was doing it with sed as there we need not to give some open/close file. (you know these things better than me just explaining my mind set Wink )
We directly replace word in a file by giving file name
like:
sed -i 's/name1/name1 \-g_id \#123' abc/xyz/my_file

and as there are thousands of entries like this i uses loop
and to learn perl i am trying this using perl.


rovf
Veteran

Mar 8, 2013, 1:40 AM

Post #6 of 7 (724 views)
Re: [abhi] unterminated `s' command [In reply to] Can't Post


Quote
I was doing it with sed as there we need not to give some open/close file.


Yes, of course, that's why you used the -i switch to sed. The -i in Perl works similar, as you have probably already seen from the link I gave you, and if this is *all* your program is supposed to do, I (being a lazy peson) would indeed using -pi for the options. BTW, you can find a good treatment of this, with an example very similar to your problem, in perldoc perlrun, where the -i switch is explained.


Kenosis
User

Mar 8, 2013, 9:22 AM

Post #7 of 7 (713 views)
Re: [abhi] unterminated `s' command [In reply to] Can't Post

The following meets your specs:

Code
use strict; 
use warnings;

my $words = pop;
chomp( my @files = <> );

push @ARGV, $words;
chomp( my @words = <> );

for my $i ( 0 .. @files - 1 ) {
push local @ARGV, $files[$i];
local $^I = '.bak';

while (<>) {
s/(\Q$words[$i]\E)/$1 . ' -g_id #123'/ge;
print;
}

unlink $files[$i] . '.bak';
}

The words file is first popped off @ARGV for later use. Next, the file paths are read into @files. The words file is restored to @ARGV, and the words are read into @words.

A for loop iterates through @files, and within that loop a local copy of @ARGV is used to read and write to each file. Note the local $^I = '.bak'; notation: that creates a temp backup and allows each file's processing.

The while loop inside the for loop contains a global substitution that looks for a file's corresponding metaquoted word. If found, it adds "-g_id #123" to it. Finally, the temporary file is deleted.

Hope this helps!

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives