Solved

Perl Write to Specific line in a file

Posted on 2016-09-29
15
49 Views
Last Modified: 2016-10-18
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
Comment
Question by:shragi
  • 7
  • 6
  • 2
15 Comments
 
LVL 11

Expert Comment

by:tel2
Comment Utility
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
 

Author Comment

by:shragi
Comment Utility
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
 

Author Comment

by:shragi
Comment Utility
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
 
LVL 11

Expert Comment

by:tel2
Comment Utility
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
 
LVL 26

Expert Comment

by:wilcoxon
Comment Utility
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
 
LVL 11

Expert Comment

by:tel2
Comment Utility
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
 

Author Comment

by:shragi
Comment Utility
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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:shragi
Comment Utility
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
 
LVL 11

Expert Comment

by:tel2
Comment Utility
> "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
 

Author Comment

by:shragi
Comment Utility
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
 
LVL 11

Expert Comment

by:tel2
Comment Utility
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
 

Author Comment

by:shragi
Comment Utility
perl
0
 
LVL 11

Expert Comment

by:tel2
Comment Utility
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
 
LVL 26

Accepted Solution

by:
wilcoxon earned 500 total points
Comment Utility
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
 
LVL 11

Expert Comment

by:tel2
Comment Utility
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

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

Here I am using Python IDLE(GUI) to write a simple program and save it, so that we can just execute it in future. Because when we write any program and exit from Python then program that we have written will be lost. So for not losing our program we…
Flask is a microframework for Python based on Werkzeug and Jinja 2. This requires you to have a good understanding of Python 2.7. Lets install Flask! To install Flask you can use a python repository for libraries tool called pip. Download this f…
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…
Learn the basics of modules and packages in Python. Every Python file is a module, ending in the suffix: .py: Modules are a collection of functions and variables.: Packages are a collection of modules.: Module functions and variables are accessed us…

763 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

6 Experts available now in Live!

Get 1:1 Help Now