• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 234
  • Last Modified:

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.
0
shragi
Asked:
shragi
  • 7
  • 6
  • 2
1 Solution
 
tel2Commented:
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?
0
 
shragiAuthor Commented:
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

0
 
shragiAuthor Commented:
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.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
tel2Commented:
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'?
0
 
wilcoxonCommented:
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

0
 
tel2Commented:
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.
0
 
shragiAuthor Commented:
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.
0
 
shragiAuthor Commented:
Hi Tel2- your code starts with "perl -F" is it command line code or can i use it in the middle of other script.
0
 
tel2Commented:
> "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.
0
 
shragiAuthor Commented:
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.
0
 
tel2Commented:
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.
0
 
shragiAuthor Commented:
perl
0
 
tel2Commented:
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.
0
 
wilcoxonCommented:
My bad, I read it as third line (rather than starting with C3).  Here's a fix:
use strict;
use warnings;
use Tie::File;
tie my @lines, 'Tie::File', filename or die "could not tie file: $!";
my $i = 0;
$i++ while ($lines[$i] !~ m{^C3,});
my @parts = split m{,}, $lines[$i];
$parts[3] = 1 if ($parts[3] == 0);
$lines[$i] = join ',', @parts;

Open in new window

1
 
tel2Commented:
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?
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

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

  • 7
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now