N0obieMonk has asked for the wisdom of the Perl Monks concerning the following question:

I am sorry for this stupid question respectable monks but I am new to perl programming and really need help with some perl code and explanations

I need some help on how to read a file, file example:

file1:"?!?!?!/pack/something/whatever.cacshdska"

I want my program to search for the word "something" and read everything except "!?!/pack/something/whatever.c" so if I print it it will output "?!?acshdska",so after it finds the word "something" it will ignore everything from it until ".c" and before it 3 characters before the first special character was found"!"

"

P.S. I am trying to convert the equivalent of every character in the file from to hex code but I don't need all the values from the file converted

{ my $input = do { open my $in, '<', $ARGV[1]; local $/; <$in> }; open my $out, '>', 'hex2.txt'; print $out unpack 'H*', $input; }

I was thinking of a split like this but I don't even know how to implement it, I'm just at the theory right now

split qr{\d\d\d(?:/\w+)+/\w+\.c}

Replies are listed 'Best First'.
Re: special pattern reading
by choroba (Cardinal) on Jan 13, 2016 at 09:51 UTC
    You can use a regular expression match.
    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; my $string = '?!?!?!/pack/something/whatever.cacshdska'; my ($before, $after) = $string =~ /(...)\W.*something.*\.c(.*)/; say for $before, $after;

    • \W stands for a "non-word" character, it matches ! and ? among other characters.
    • a dot matches any character except a newline.
    • * means "the previous thing repeated zero or more times"
    • parentheses create "capture groups", what matches their contents gets returned (in this case, there are 2 capture groups, and we assing them to $before and $after).
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      your version reads the first "3" characters and everything after ".c" I need to read everything until the 3rd special character before the "/"

      #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; my $string = '!2!ab!!!!/pack/something/whatever.cacshdska'; my ($before, $after) = $string =~ /(...)\W.*something.*\.c(.*)/; say for $before, $after;

      Output is "!2!acshdska" while I need output to be "!2!ab!acshdska" sorry if I wasn't clear enough ...my bad.

        OK, I think I understand now. Or don't I?
        #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; for my $string ( '?!?!?!/pack/something/whatever.cacshdska', '!2!ab!!!!/pack/something/whatever.cacshdska', ) { my ($before, $after) = $string =~ m{(.*)..\W/.*\.c(.*)}; say "$before | $after"; }
        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: special pattern reading
by hippo (Archbishop) on Jan 13, 2016 at 09:51 UTC

    If I understand you correctly then this substitution should be all you need for manipulating the filename:

    use strict; use warnings; my $file = '?!?!?!/pack/something/whatever.cacshdska'; $file =~ s/..![^!]*something.*\.c//; print $file . "\n";

      Why is my version not working?

      use strict; use warnings; { my $input = do { open my $in, '<', '1.txt'; local $/; <$in> }; until ( eof $in){ my $file = <$in>; $file =~ s/..![^!]*something.*\.c//; print $file . "\n"; }

        Your code doesn't compile:

        $ perl -cw 1152653.pl Global symbol "$in" requires explicit package name at 1152653.pl line +9. Global symbol "$in" requires explicit package name at 1152653.pl line +11. Missing right curly or square bracket at 1152653.pl line 14, at end of + line syntax error at 1152653.pl line 14, at EOF 1152653.pl had compilation errors.

        You'll need to fix the errant opening brace and the scoping of $in.

        Update: Here's a working rewrite of your script above:

        use strict; use warnings; open my $in, '<', '1.txt' or die "Cannot open 1.txt: $!"; while (my $file = <$in>) { $file =~ s/..![^!]*something.*\.c//; print $file; } close $in;

        And here's what happens when I run it:

        $ cat 1.txt foo ?!?!?!/pack/something/whatever.cacshdska bar $ perl fixup.pl foo ?!?acshdska bar
Re: special pattern reading
by Anonymous Monk on Jan 13, 2016 at 09:49 UTC