Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

How to change @ symbol of lines that are using the same @ symbol as the input record separator in Perl code?

Posted on 2011-02-10
15
Medium Priority
?
810 Views
Last Modified: 2012-05-11
I have a big problem in which certain lines start with the @ symbol, the same as the start of line as the @ symbol use as the input record separator.

for example,

@test_scsi 1 <------ use as a input record separator
1. slslslslslslsls
@ this slslslslslslslsls  <--------- need to change this @ symbol to something different, pref. #
2. dkdkdkdkdkdkd
dkdkdkdkdkd
3. dkdkdkdkdkdk
@ trying again  <--------- need to change this @ symbol to something different, pref. #
@test_scsi 2 <------ use as a input record separator
1. slslslslslslsls
@ this slslslslslslslsls  <--------- need to change this @ symbol to something different, pref. #
2. dkdkdkdkdkdkd
dkdkdkdkdkd
3. dkdkdkdkdkdk
@ trying again  <--------- need to change this @ symbol to something different, pref. #
@test_scsi 3 <------ use as a input record separator
1. slslslslslslsls
@ this slslslslslslslsls  <--------- need to change this @ symbol to something different, pref. #
2. dkdkdkdkdkdkd
dkdkdkdkdkd
3. dkdkdkdkdkdk
@ trying again  <--------- need to change this @ symbol to something different, pref. #
@test_scsi 4 <------ use as a input record separator
1. slslslslslslsls
@ this slslslslslslslsls  <--------- need to change this @ symbol to something different, pref. #
2. dkdkdkdkdkdkd
dkdkdkdkdkd
3. dkdkdkdkdkdk
@ trying again  <--------- need to change this @ symbol to something different, pref. #
@test_scsi 5 <------ use as a input record separator
1. slslslslslslsls
@ this slslslslslslslsls  <--------- need to change this @ symbol to something different, pref. #
2. dkdkdkdkdkdkd
dkdkdkdkdkd
3. dkdkdkdkdkdk
@ trying again  <--------- need to change this @ symbol to something different, pref. #


Here's test the code I put together based on the pattern that the not needed @ symbol follows a line number above but not working. I'm not getting any output.

#!/usr/bin/perl

use strict;
use warnings;

$/='@';

open FH,'<','scsi_test' or die $!;

while (<FH>)
{
    if(/(^[1-40]\..+[^\n]+)\n(\^@.+[^\n]+)/ms)
    {
       print $2;
    }
}

0
Comment
Question by:areyouready344
  • 8
  • 4
  • 3
15 Comments
 
LVL 85

Assisted Solution

by:ozo
ozo earned 856 total points
ID: 34865614
if you want to change @s that are followed by space
perl -i.bak -pe 's/^@ /# /' scsi_test
0
 
LVL 27

Assisted Solution

by:wilcoxon
wilcoxon earned 1144 total points
ID: 34865632
Or if all of your actual separators begin @test then you could set $/ = '@test' (rather than the $/ = '@' I think you currently have).
0
 

Author Comment

by:areyouready344
ID: 34865677
Ozo, i need to make a different between input record symbol of @ and the @ symbols at the wrong locations which are following the above number lines.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 85

Accepted Solution

by:
ozo earned 856 total points
ID: 34865773
perl -MYAPE::Regex::explain -e 'print YAPE::Regex::Explain->new(qr/(^[1-40]\..+[^\n]+)\n(\^@.+[^\n]+)/ms)->explain'
The regular expression:

(?ms-ix:(^[1-40]\..+[^\n]+)\n(\^@.+[^\n]+))

matches as follows:
 
NODE                     EXPLANATION
----------------------------------------------------------------------
(?ms-ix:                 group, but do not capture (with ^ and $
                         matching start and end of line) (with .
                         matching \n) (case-sensitive) (matching
                         whitespace and # normally):
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    ^                        the beginning of a "line"
----------------------------------------------------------------------
    [1-40]                   any character of: '1' to '4', '0'
----------------------------------------------------------------------
    \.                       '.'
----------------------------------------------------------------------
    .+                       any character (1 or more times (matching
                             the most amount possible))
----------------------------------------------------------------------
    [^\n]+                   any character except: '\n' (newline) (1
                             or more times (matching the most amount
                             possible))
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
  \n                       '\n' (newline)
----------------------------------------------------------------------
  (                        group and capture to \2:
----------------------------------------------------------------------
    \^                       '^'
----------------------------------------------------------------------
    @                        '@'
----------------------------------------------------------------------
    .+                       any character (1 or more times (matching
                             the most amount possible))
----------------------------------------------------------------------
    [^\n]+                   any character except: '\n' (newline) (1
                             or more times (matching the most amount
                             possible))
----------------------------------------------------------------------
  )                        end of \2
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------

Since there is no literal '^' character in your example, it would never match.
Also, since you are splitting on '@' the @ would be the last character in each record, so there would be no . or [^\n] following

perhaps you would prefer
    if(/(^[1-40]\..+[^\n]+)\n(^@.*[^\n]*)/ms)
    {
       print $1;
    }

or

$/='@test';

open FH,'<','scsi_test' or die $!;

while (<FH>)
{
    if(/(^[01-4]\..+?[^\n]+)\n(^@.*[^\n]*)/ms)
    {
       print $2;
    }
}

or

$/='@test';

open FH,'<','scsi_test' or die $!;

while (<FH>)
{
    s/(^\d\.[^\n]+\n)\@/$1#/msg;
    print;
}

0
 

Author Comment

by:areyouready344
ID: 34865867
there maybe a chance that @test maybe listed below the number lines. Can Perl grep be used in this case? Or is there another solution would involving the input record separator? Super Thanks.....
0
 

Author Comment

by:areyouready344
ID: 34865901
Can i just read in the whole file and search for that pattern by passing the @test input record separator?
0
 
LVL 27

Assisted Solution

by:wilcoxon
wilcoxon earned 1144 total points
ID: 34865985
Personally, unless @test can only appear as a record separator or all separators are @test and all non-separators are @ followed by space, I'd either read the file in line-by-line and manually process it or (more probably) use Tie::File to treat the whole file as an array (and process it from there).
0
 

Author Comment

by:areyouready344
ID: 34865989
I need the search for the pattern below regardless of the input record separator. Is this possible?

[1-40]\.*\n
@.*
0
 
LVL 27

Assisted Solution

by:wilcoxon
wilcoxon earned 1144 total points
ID: 34866073
Sure...

m{[0-4]\.[^\n]+\n\@.*}ms

Changed [1-40] to [0-4] to make it more explicit what it does.
Changed \.* to \.[^\n]+ as the first would look for repeating literal periods.
0
 
LVL 27

Assisted Solution

by:wilcoxon
wilcoxon earned 1144 total points
ID: 34866082
I'm unclear exactly what you're trying to do with that pattern so I'm not sure if it needs further modification or not.
0
 

Author Comment

by:areyouready344
ID: 34866283
That didn't work Wilcoxon because it list the input record separator if the number line is above it. I get the data, that is below the @input record separator from the exs server and don't wanna change it. Is regex useful in this situation?
0
 
LVL 85

Assisted Solution

by:ozo
ozo earned 856 total points
ID: 34866370
perl -0100i.bak -pe 's/(^\d\..*\n)@/$1#/m' scsi_test
0
 

Author Comment

by:areyouready344
ID: 34906942
thanks all, I fix this problem by taking Ozo suggestion in a previous case ticket by changing the input record separator from @text to __Data__ . The new record previous interference with the data records and solved this problem
0
 

Author Comment

by:areyouready344
ID: 34906950
The problem was with the structuring of the data records.
0
 

Author Closing Comment

by:areyouready344
ID: 34906982
the problem was with the structuring of the data records
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

824 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question