Avatar of shragi
shragi
Flag for India asked on

Perl Write to Specific line in a file

Hi - I have the below file format and i want to update a value in the line that start with C3

C1, 2,2,0,9292016_101425, 0, 9292016_101428, 0, 9292016_101428
C2, 1,2,0,9292016_101425, 0, 9292016_101428
C3, 2,2,0,9292016_101425, 0, 9292016_101428, 0, 9292016_101428

I want to update the above C3 line as below (just changed 0 to 1 in the fourth field)
C3, 2,2,1,9292016_101425, 0, 9292016_101428, 0, 9292016_101428

the problem i have is i know how to append a string to a file but i dont know how to modify a particular line content in a file.
Any help will be greatly appreciated.
PerlShell ScriptingPython

Avatar of undefined
Last Comment
tel2

8/22/2022 - Mon
tel2

To read from oldfile and write to newfile:
    perl -pe 's/^C3,.*,.*,\K0,/1,/' oldfile >newfile
or to update oldfile itself:
    perl -i -pe 's/^C3,.*,.*,\K0,/1,/' oldfile
or to backup the original file to oldfile.bak and then update oldfile:
    perl -i.bak -pe 's/^C3,.*,.*,\K0,/1,/' oldfile

Too lengthy?
shragi

ASKER
Hi Tel2 - in the below line if i want to update fourth field value from 0 to 1 the above code works but what if i want to change 6th field value from 0 to 1 or let us say 8th field value from 0 to 1.
How do you modify such things, i expected in the form of field number but the regular expression you gave me i did not understand how it works.

C3, 2,2,0,9292016_101425, 0, 9292016_101428, 0, 9292016_101428

Open in new window

shragi

ASKER
the field position 4th or 6th or 8th are not fixed all the time
my other code determine which value should be updated on the line, so was looking for something in terms of field number.
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
tel2

Hi shrangi,

It could save a lot of time if you make such expectations of flexibility clear in your original post, in future.

Are you wanting to replace the Nth field in the 'C3' line with '1' ONLY if it is '0'?  Or can all such values be changed to '1'?
wilcoxon

This is how I'd do it...
use strict;
use warnings;
use Tie::File;
tie my @lines, 'Tie::File', filename or die "could not tie file: $!";
my @parts = split m{,}, $lines[2];
$parts[3] = 1 if ($parts[3] == 0);
$lines[2] = join ',', @parts;

Open in new window

tel2

Is this what you're after, shrangi?
    perl -F, -ane '$F[3]="1" if /^C3,/ && $F[3] eq "0";print join(",",@F)' oldfile >newfile
or, if you also want to refer to the 1st field by index:
    perl -F, -ane '$F[3]="1" if $F[0] eq "C3" && $F[3] eq "0";print join(",",@F)' oldfile >newfile

The 2 instances of "$F[3]" refer to the 4th field, because $F[0] is the 1st field.
So, change that to whatever field is required.

But please answer the question in my previous post, because I may be able to simplify this code a bit (or even a byte) more.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
shragi

ASKER
Hi Tel2 - yes i want to replace the Nth field in the 'C3' line with '1' ONLY if it is '0' - not all
Hi wilcoxon - in your code how do you determine the line starts with C3.
shragi

ASKER
Hi Tel2- your code starts with "perl -F" is it command line code or can i use it in the middle of other script.
tel2

> "Hi Tel2- your code starts with "perl -F" is it command line code or can i use it in the middle of other script."

Thank you again for saving this information until this late stage.  You could have explained that requirement in your previous post, or even your original post.

What kind of "other script" are you going to put this in?  Perl?  Shell?  Python?  You posted this question in all those topic areas, so I can't tell what you want.
If the "other script" is a shell script, you can use my one-liner as is.
If the "other script" is a Perl script, maybe you should use wilcoxon's solution, which looks pretty concise for a non-one-liner.
Your help has saved me hundreds of hours of internet surfing.
fblack61
shragi

ASKER
Sorry tel2 I was stupid not to be clear.
Wincoxon solution is good except that i am not sure how does he find the line start with C3.
tel2

Again...
What kind of "other script" are you going to put this in?  Perl?  Shell?  Python?  You posted this question in all those topic areas, so I can't tell what you want.
shragi

ASKER
perl
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
tel2

So why did you include the Shell Scripting and Python topic areas, shragi?  Doing so could result in experts wasting time providing solutions in the wrong language.

In general, if you want some programming done, I suggest you specify:
- Language
- Whether you want it embedded in your script, or a one-liner, or either is OK.
- Operating system.
The 1st and 3rd of these can often be obvious because of the topic areas you have chosen, but it's better to say it plainly.

But I accept your above apology, and maybe I should have asked more questions before wasting time on this.
ASKER CERTIFIED SOLUTION
wilcoxon

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
tel2

Hi wilcoxon,

Your code seems to work for test data supplied, but...

1. It crashes if the 4th field is not a number (e.g. absent or has a leading space), like these:
C3, 2,2,,9292016_101425, 0, 9292016_101428, 0, 9292016_101428
C3, 2,2, 0,9292016_101425, 0, 9292016_101428, 0, 9292016_101428

2. If a line starts with C3 but doesn't have a 0 in the 4th field, then no futher attempt is made to find a line which starts with C3 and has a 0.

shragi, are either of the above input data scenarios possibly going to occur?