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
749 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 84

Assisted Solution

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

Assisted Solution

by:wilcoxon
wilcoxon earned 286 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
 
LVL 84

Accepted Solution

by:
ozo earned 214 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 26

Assisted Solution

by:wilcoxon
wilcoxon earned 286 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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

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 26

Assisted Solution

by:wilcoxon
wilcoxon earned 286 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 26

Assisted Solution

by:wilcoxon
wilcoxon earned 286 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 84

Assisted Solution

by:ozo
ozo earned 214 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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
perl search and replace 6 161
Move Function in Perl Script 2 58
Edit Odbc.ini using perl module 2 69
Perl modules on linux ec2 3 85
I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
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…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

758 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now