search text file, find substring, beginner help pls. 
Author Message
 search text file, find substring, beginner help pls.

I was asked to write a batch file which would get the UserTemplates
directory from the NT registry and, using this value, copy a file
there because some users have problems copying a file to their
templates directory. I tried to do it in an ms-dos batch file but ran
into probs. with a multi-line pathname (regedit saves the value as hex
and it took up 3 lines). I was asked to use Perl which I've never used
but had success today writing to a file and the pathname shows up in
ascii which is very good. Question: how do I search a file for an
entry but then get only part of the line? My batch file saved the
registry value (UserTemplates=C:\Documents and Settings) and I was
able to search for 'UserTemplates' and get everything after the '='
and save it to a variable. How can I do this with Perl?
Here's the beginning lines from the batch file:

:: Export settings from registry to a temporary file
START /W REGEDIT /E  %Temp%.\test_reg.sb
"HKEY_CURRENT_USER\Software\Microsoft\Office\9.0\Common\General"
:: Read from the temporary file and store in variable
FOR /F "tokens=1,* delims==" %%A IN ('TYPE %Temp%.\test_reg.sb ^| FIND
"UserTemplates"') DO SET iTemplate=%%B

In my Perl script, I can save the values to a file but I don't know
how to search the file to find the value after 'UserTemplates='. I
want to be able to copy a templates .dot file to this directory.

use Win32::Registry;
$p = "Software\\Microsoft\\Office\\9.0\\Common\\General";
$main::HKEY_CURRENT_USER->Open($p, $General) ||
        die "Open: $!";
open(fileOUT, ">sb.txt") || dienice("Can't open sb.txt: $!");
seek(fileOUT, 0, 0);

$General->GetValues(\%vals);
foreach $k (keys %vals) {
        $key = $vals{$k};
print fileOUT "$$key[0] = $$key[2]\n";

Quote:
}

close(fileOUT);

I've been looking thru Learning Perl on Win32 Systems and Advanced
Perl Programming (books here at work) but I can't find documentation
on how to search a file.
Thanks,
Suzanne



Fri, 20 May 2005 23:07:01 GMT  
 search text file, find substring, beginner help pls.
Also sprach Suzanne Barron:

Quote:
> I was asked to write a batch file which would get the UserTemplates
> directory from the NT registry and, using this value, copy a file
> there because some users have problems copying a file to their
> templates directory. I tried to do it in an ms-dos batch file but ran
> into probs. with a multi-line pathname (regedit saves the value as hex
> and it took up 3 lines). I was asked to use Perl which I've never used
> but had success today writing to a file and the pathname shows up in
> ascii which is very good. Question: how do I search a file for an
> entry but then get only part of the line? My batch file saved the
> registry value (UserTemplates=C:\Documents and Settings) and I was
> able to search for 'UserTemplates' and get everything after the '='
> and save it to a variable. How can I do this with Perl?
> Here's the beginning lines from the batch file:

>:: Export settings from registry to a temporary file
> START /W REGEDIT /E  %Temp%.\test_reg.sb
> "HKEY_CURRENT_USER\Software\Microsoft\Office\9.0\Common\General"
>:: Read from the temporary file and store in variable
> FOR /F "tokens=1,* delims==" %%A IN ('TYPE %Temp%.\test_reg.sb ^| FIND
> "UserTemplates"') DO SET iTemplate=%%B

Uggh, I can't even decipher that.

Quote:
> In my Perl script, I can save the values to a file but I don't know
> how to search the file to find the value after 'UserTemplates='. I
> want to be able to copy a templates .dot file to this directory.

That's a good job for a regular expression. You don't tell us how the
line exactly looks, so I suspect you want everything following
'UserTemplates='.

Assuming you have a variable with a line containing such an entry:

    my ($wanted) = $line =~ /UserTemplates=(.*)/;
          # ^--------<------<-------<-------|--|

$line is matched against the pattern 'UserTemplates=(.*)'. The parens ()
tell perl to capture everything that matches the pattern in between the
parens. This is '.*' here which means: Any character zero or more times,
but be greedy. That means, match as much as possible.

Since the pattern matching ( $var =~ /pattern/ ) happens on the right
hand side of a list expression (called list context), the match returns
everything that was returned by the capturing pair of parens in the
pattern. We had only one pair of such parens here and so all of that is
stored in $wanted. Similarily:

    my ($first, $second) = $line =~ /key1=(.*?)key2=(.*)/;

where the stuff matched by '.*?' (match anything, but as short as
possible) would go into $first while the matching of '.*' into $second.

Quote:
> use Win32::Registry;
> $p = "Software\\Microsoft\\Office\\9.0\\Common\\General";
> $main::HKEY_CURRENT_USER->Open($p, $General) ||
>         die "Open: $!";
> open(fileOUT, ">sb.txt") || dienice("Can't open sb.txt: $!");
> seek(fileOUT, 0, 0);

> $General->GetValues(\%vals);
> foreach $k (keys %vals) {
>    $key = $vals{$k};
> print fileOUT "$$key[0] = $$key[2]\n";

> }
> close(fileOUT);

Considering this was your first contact with Perl, this already looks
quite promising.

Quote:
> I've been looking thru Learning Perl on Win32 Systems and Advanced
> Perl Programming (books here at work) but I can't find documentation
> on how to search a file.

Searching a file commonly happens by traversing the file linewise and do
some tests on each of these lines. In your above code you open the file
for writing, whereas you now want a read-access:

    open IN, "<sb.txt" or die $!;
    while (<IN>) { # as long as a readline on the file produces something
        my ($templates) = $_ =~ /UserTemplates=(.*)/;
        ...
    }

The 'while(<HANDLE>)' idiom stores the next chunk read from the file in
the special variable $_. $_ is also the variable that is the default
target of many Perl functions and operators, so the match can be written
more nicely:

    while (<IN>) {
        my ($templates) = /UserTemplaces=(.*)/;
        ...
    }
    close IN;

Which leaves one question: Do you really need this intermediate step of
writing to the file and afterwards retrieving its content? A pattern
match can be applied to any scalar-ish Perl value:

    ($res) = "string" =~ /PATTERN/;
    ($res) = $string  =~ /PATTERN/;
    ($res) = $array[0] =~ /PATTERN/;
    ($res) = $hash{key} =~ /PATTERN/;
    ($res) = $ref->{key} =~ /PATTERN/;
    # etc

Perhaps you can diddle the match somewhere into your foreach loop and
thus save the file altogether.

By the way, all of the above techniques can be found in the
documentation shipped with Perl (these docs are much better than any
book I know of, even suitable for those new to Perl):

    perldoc perlretut   (regular expression tutorial)
    perldoc perlre      (regular expression reference)
    perldoc perlopentut (tutorial for open())
    perldoc perlop      (Perl operators, m// is one of them)
    perldoc -f FUNCTION (documentation for particular function)
    perldoc perlfunc    (all functions, with categorization)

Since you are using Perl under Windows, you probably have ActiveState's
Perl in which case all of these manpages come as html-documents with
nice cross-linking.

Tassilo
--

pam{rekcahbus;})(rekcah{lrePbus;})(lreP{rehtonabus;})(rehtona{tsuJbus!;
$_=reverse;s/sub/(reverse"bus").chr(32)/xge;tr~\n~~d;eval;



Fri, 20 May 2005 23:53:03 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Help for a beginner pls.

2. BEGINNER'S question re searching for text

3. Win95, Find::File, and PLS

4. Pls help - raising text window

5. Help with text file searches on BSD Unix

6. Help needed - search utility in text files

7. Help with text file searches on BSD Unix

8. help with perl script that searches through a text file

9. Help with multiple text files, search and replace, rename

10. Help searching text file

11. Help with text file searches on BSD Unix

12. Help with opening text files and searching them.

 

 
Powered by phpBB® Forum Software