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

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

Hey Guys So I don't know how easy/hard this is. I have searched the internet high and low. What I need is to print a certain part of a line in a file. Here is an example line.

 j1000010017 6790194100109201301092013THIS TO BE PRINTED  M PW09-3PY248005BIK00

So what I need is to print 20 characters(no matter what they are) from the 38th character (THIS TO BE PRINTED ) and on the same line 3 characters from the 68th character (248). The only what I can think of is the substr method but I've not used it before and am not sure of the syntax and whether I could pull to different locations on the same line. Please Help! Thanks Jim

Replies are listed 'Best First'.
Re: Printing set characters from offset.
by mtmcc (Hermit) on Sep 23, 2013 at 14:36 UTC
    substr is the easiest way.

    #!/usr/bin/perl use strict; use warnings; while (<DATA>) { my $first = substr $_, 37, 20; my $second = substr $_, 67, 3; print STDOUT "FIRST: $first\nSECOND: $second\n\n"; } __DATA__ j1000010017 6790194100109201301092013THIS TO BE PRINTED M PW09-3PY248 +005BIK00

      Thanks, this worked perfectly.
Re: Printing set characters from offset.
by Corion (Patriarch) on Sep 23, 2013 at 14:31 UTC

    substr shows various uses of substr. Which parts did you find problematic? Which parts have you applied to your problem, and what were the results?

      Well, I did try:

       print{ substr(( my $lines, $schemePOS, 20) and ( my $lines, $abiPOS, 3)); }

      But I got the following:
      Global symbol "$lines" requires explicit package name at ./efhv2.pl li +ne 27. Global symbol "$lines" requires explicit package name at ./efhv2.pl li +ne 27. Not enough arguments for substr at ./efhv2.pl line 27, near "))"
      I'm not even sure if you can do that with the substr method. But as I say I'm not sure of the syntax for it.
        A couple issues here.
        1. my is used to declare a lexical variable. In general, my $lines should appear once in your code, when you first use it. If you are going through a file, it might look like:

          while (my $lines = <$fh>) {...
          The text you have written declares two new, undefined variables named $lines.
        2. and is a logical operator. The code you wrote takes two lists (( my $lines, $schemePOS, 20) and ( my $lines, $abiPOS, 3)) and tests if they are both logically true. Since the lists are both longer than 0 elements, and returns a true value, and this true value is then fed into substr, which expects at least two arguments, thus the returned error.

        3. Lastly, print takes a list (parentheses), not a block (curly brackets) as an argument. Either

          print $arg1, $arg2, ...
          or, if you want to have a clear delimiter,
          print($arg1, $arg2, ...)
        The code you meant to write would probably look like:
        print substr($lines, $schemePOS, 20), substr($lines, $abiPOS, 3);
        I have fed print a list of two values, which are the return values of the substrs. There are a number of ways to do this, but they'd all fit this general pattern.

        Given your apparent familiarity with the language, I'd suggest going through some introductory learning materials. http://learn.perl.org has a number of resources available, including free access to Beginning Perl.


        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

        That isn't what the "and" operator does. If you want to print 2 substrings, call substr twice, eg:

         print substr ($lines, $o1, $l1) . substr ($lines, $o2, $l2);

        Please show a short, self-contained program that exhibits the problem.

        Your code is almost valid Perl, but it is highly nonsensical. Maybe you can explain in English what the characters you wrote are supposed to mean.

        I don't know how to advise you further, other than to learn Perl from a tutorial. You cannot take English sentences and hope that Perl will interpret them as you intend.

Re: Printing set characters from offset.
by AnomalousMonk (Archbishop) on Sep 23, 2013 at 23:00 UTC
    ... substr ... not sure of the syntax ...

    In addition to the on-line Perl documentation for substr linked by Corion, there's also
        perldoc -f substr
    from your friendly local command line. See perldoc (or
        perldoc perldoc
    from the command line).

Re: Printing set characters from offset.
by ww (Archbishop) on Sep 23, 2013 at 17:55 UTC
    Perhaps you meant to code you solution like this:
    #!/usr/bin/perl use 5.016; use warnings; # 1055294 my $line = ' j1000010017 6790194100109201301092013THIS TO BE PRINTED +M PW09-3PY248005BIK00 '; say substr( $line, 38, 20); say substr( $line, 68, 3); =head EXECUTION C:\>D:\_wo\1055294.pl THIS TO BE PRINTED 248 =cut

    Explanation: perldoc -f substr.

    Because you didn't RTFM, you owe apologies to all those electrons which were inconvenienced by the creation of this post.