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

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;
    }
}

areyouready344Asked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
ozoConnect With a Mentor Commented:
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
 
ozoConnect With a Mentor Commented:
if you want to change @s that are followed by space
perl -i.bak -pe 's/^@ /# /' scsi_test
0
 
wilcoxonConnect With a Mentor Commented:
Or if all of your actual separators begin @test then you could set $/ = '@test' (rather than the $/ = '@' I think you currently have).
0
[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

 
areyouready344Author Commented:
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
 
areyouready344Author Commented:
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
 
areyouready344Author Commented:
Can i just read in the whole file and search for that pattern by passing the @test input record separator?
0
 
wilcoxonConnect With a Mentor Commented:
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
 
areyouready344Author Commented:
I need the search for the pattern below regardless of the input record separator. Is this possible?

[1-40]\.*\n
@.*
0
 
wilcoxonConnect With a Mentor Commented:
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
 
wilcoxonConnect With a Mentor Commented:
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
 
areyouready344Author Commented:
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
 
ozoConnect With a Mentor Commented:
perl -0100i.bak -pe 's/(^\d\..*\n)@/$1#/m' scsi_test
0
 
areyouready344Author Commented:
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
 
areyouready344Author Commented:
The problem was with the structuring of the data records.
0
 
areyouready344Author Commented:
the problem was with the structuring of the data records
0
All Courses

From novice to tech pro — start learning today.