Adding text to file on certain lines with(special characters)


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Adding text to file on certain lines with(special characters)
# 1  
Old 12-15-2009
Adding text to file on certain lines with(special characters)

I need to add "new lines" of text with special characters, to specific lines in the file. There are 3 modifications needed. Been testing 2 here without success.

Code:
#!/usr/bin/perl

use FileHandle;
$file=FileHandle->new;
$FILENAME="/opt/etc/usr/file.txt";
$file->open ("<$FILENAME") or die ("Error: $!\n");
while (<$file>) {
        $count++;
        if ($count=39) {
print qq[RM="rm2"];}
if ($count=47) {
print qq[$RM]
}
if ($count= 53)
print qq[rmdesc="Result process"]
exit;


Last edited by Scott; 12-15-2009 at 03:41 PM.. Reason: Please use code tags
# 2  
Old 12-15-2009
Your Perl program is incorrect syntax-wise. You may want to look up basic conditions and loop structures in the documentation or a good textbook.

Maybe this is what you are looking for -

Code:
$
$ cat -n f7
     1  this is line 1
     2  this is line 2
     3  this is line 3
     4  this is line 4
     5  this is line 5
     6  this is line 6
     7  this is line 7
     8  this is line 8
     9  this is line 9
    10  this is line 10
$
$
$ perl -lne 'BEGIN {$RM="BLAH"}
             if ($. == 3) {print qq(RM="rm2")}
             elsif ($. == 5) {print qq($RM)}
             elsif ($. == 7) {print qq(rmdesc="Result process")}
             else {print}' f7
this is line 1
this is line 2
RM="rm2"
this is line 4
BLAH
this is line 6
rmdesc="Result process"
this is line 8
this is line 9
this is line 10
$
$

tyler_durden
# 3  
Old 12-15-2009
I've been working on a PERL script for work. This would be day 3 so couldn't agree more that perhaps PERL is something worth pursuing. I couldn't get your script to work. Would you mind explaining it? Is it a command line script because that will not work. Once I figure out how to insert new lines of text into existing file my script will be finished. I have 20 lines of code using File::Copy / 20 lines of s//. If there is already text on line 30 will this overwrite or insert in between lines 29 & 30?
# 4  
Old 12-15-2009
Debian

Quote:
Originally Posted by A4ron4perl
... I couldn't get your script to work. ...
It would be much more helpful if you actually cut and paste what you tried, and show the error message clearly.

Quote:
... Would you mind explaining it? ...
Sure.
Code:
cat -n f7

"f7" is my test file. "cat -n" displays the contents of my test file with the line numbers printed on the left. I've created the test file in such a way that it's easy to figure out the line number by looking at the content. For example, the first line says "this is line 1", 8th line says "this is line 8" and so on. That way, after the perl script is run, you can easily figure out-

(a) if some text was added before or after a line
(b) if some text replaced a line

Code:
$ perl -lne 'BEGIN {$RM="BLAH"}

- "perl" invokes the Perl interpreter
- "l", "n" and "e" are the command-line options.
- "l" prints a newline after a "print" command so you do not have to add an explicit "\n" in your "print" command.
- "n" creates a "while (<>){...}" loop around the program i.e. it executes the perl program on each line of the input stream (file "f7" in my case)
- "e" specifies that a program follows in the single quotes after it

- "BEGIN {$RM="BLAH"}" this is where all initialization resides. Code inside BEGIN executes only once - at the beginning, before the file is processed. Over here, the variable $RM is set to "BLAH" only once. If I do not put it inside "BEGIN", it will be unnecessarily initialized for every line in the file f7.

Code:
             if ($. == 3) {print qq(RM="rm2")}

$. is a special Perl variable that stores the line number of the input stream that is being processed currently. In my case the input stream is the file "f7". It is similar to the "NR" variable of awk. Perl has an extensive list of such variables that are of the form "$" followed by (I guess) almost every special character on your keyboard.

"qq" is a quote-like operator that is used along with "print" to print double quoted interpolated strings.

Code:
             elsif ($. == 5) {print qq($RM)}  
             elsif ($. == 7) {print qq(rmdesc="Result process")}
             else {print}' f7

"elsif" and "else" is used because $. - the line number can only be one of 3, 5, 7, something else. Note that "if ... elsif ... else" is preferable to "if(){...} if(){...} if(){...}" over here for each line.

So what the conditional loop does is this -

(a) if current line number is 3 then print RM="rm2" to the console, which means the original line 3 in the file f7 is not displayed.

(b) otherwise if current line number is 5 then print value of $RM i.e. BLAH, which means that the original line 5 in the file f7 is not displayed.

(c) otherwise if current line number is 7 then print rmdesc="Result process", which means that the original line 7 in the file f7 is not displayed.

(d) for every other line, print the original content in the file.

Note that the script reads the file and shows something to the standard output. That "something" could be original file content or something you want to display. It does not replace or alter or modify the file contents in any way.

Quote:
...
Is it a command line script because that will not work.
...
Yes, it's called a "one-liner". Not sure what makes you think it will not work. It may not work for your requirements, but it does work as seen in the output of my previous post.

Quote:
...If there is already text on line 30 will this overwrite or insert in between lines 29 & 30? ...
Again, if there is some text on line 30, and if you change the if/elsif condition accordingly, then this one-liner will read line 30 and print something else to the standard output (console). That's all it does. The file will remain as it was earlier.

HTH,
tyler_durden
# 5  
Old 12-15-2009
very nice job, tyler.
# 6  
Old 12-15-2009
I would love to use a one-liner from the command line. This is going into a larger script. This is my first script with perl and I am not a programmer. Opening a file is still awkward to me vs. something you are so used to it doesn't even register anymore.

What i would like to accomplish. Open a file. Write to file without overwriting everything or anything. If you had "vi" editing a file using :set number. I want to edit lines 31,39,40 etc without overwriting whats on those lines yet add new line with text.

Here is what I have that does not work Smilie Does what I want to accomplish make sense and am I close?

Code:
#!/usr/bin/perl
 
$file="/opt/control/etc/status";
open(FH, ">>$file")
or die "Can't open file: $!";
 
while (<FH>) {
        $count++; }
        if ($count==31) {
print FH qq[RM="rm2"];}
if ($count==40) {
print FH qq[$RM]
}
if ($count==43) {
print FH qq[rmDESC="Result Manager2"\n];
}
close FH;
exit;


Quote:
Originally Posted by durden_tyler
It would be much more helpful if you actually cut and paste what you tried, and show the error message clearly.



Sure.
Code:
cat -n f7

"f7" is my test file. "cat -n" displays the contents of my test file with the line numbers printed on the left. I've created the test file in such a way that it's easy to figure out the line number by looking at the content. For example, the first line says "this is line 1", 8th line says "this is line 8" and so on. That way, after the perl script is run, you can easily figure out-

(a) if some text was added before or after a line
(b) if some text replaced a line

Code:
$ perl -lne 'BEGIN {$RM="BLAH"}

- "perl" invokes the Perl interpreter
- "l", "n" and "e" are the command-line options.
- "l" prints a newline after a "print" command so you do not have to add an explicit "\n" in your "print" command.
- "n" creates a "while (<>){...}" loop around the program i.e. it executes the perl program on each line of the input stream (file "f7" in my case)
- "e" specifies that a program follows in the single quotes after it

- "BEGIN {$RM="BLAH"}" this is where all initialization resides. Code inside BEGIN executes only once - at the beginning, before the file is processed. Over here, the variable $RM is set to "BLAH" only once. If I do not put it inside "BEGIN", it will be unnecessarily initialized for every line in the file f7.

Code:
             if ($. == 3) {print qq(RM="rm2")}

$. is a special Perl variable that stores the line number of the input stream that is being processed currently. In my case the input stream is the file "f7". It is similar to the "NR" variable of awk. Perl has an extensive list of such variables that are of the form "$" followed by (I guess) almost every special character on your keyboard.

"qq" is a quote-like operator that is used along with "print" to print double quoted interpolated strings.

Code:
             elsif ($. == 5) {print qq($RM)}  
             elsif ($. == 7) {print qq(rmdesc="Result process")}
             else {print}' f7

"elsif" and "else" is used because $. - the line number can only be one of 3, 5, 7, something else. Note that "if ... elsif ... else" is preferable to "if(){...} if(){...} if(){...}" over here for each line.

So what the conditional loop does is this -

(a) if current line number is 3 then print RM="rm2" to the console, which means the original line 3 in the file f7 is not displayed.

(b) otherwise if current line number is 5 then print value of $RM i.e. BLAH, which means that the original line 5 in the file f7 is not displayed.

(c) otherwise if current line number is 7 then print rmdesc="Result process", which means that the original line 7 in the file f7 is not displayed.

(d) for every other line, print the original content in the file.

Note that the script reads the file and shows something to the standard output. That "something" could be original file content or something you want to display. It does not replace or alter or modify the file contents in any way.



Yes, it's called a "one-liner". Not sure what makes you think it will not work. It may not work for your requirements, but it does work as seen in the output of my previous post.



Again, if there is some text on line 30, and if you change the if/elsif condition accordingly, then this one-liner will read line 30 and print something else to the standard output (console). That's all it does. The file will remain as it was earlier.

HTH,
tyler_durden

Last edited by Scott; 12-15-2009 at 07:48 PM.. Reason: Added code tags
# 7  
Old 12-15-2009
Quote:
Originally Posted by A4ron4perl
I would love to use a one-liner from the command line. This is going into a larger script. This is my first script with perl and I am not a programmer. Opening a file is still awkward to me vs. something you are so used to it doesn't even register anymore.

What i would like to accomplish. Open a file. Write to file without overwriting everything or anything. If you had "vi" editing a file using :set number. I want to edit lines 31,39,40 etc without overwriting whats on those lines yet add new line with text.

Here is what I have that does not work Smilie Does what I want to accomplish make sense and am I close?

#!/usr/bin/perl

$file="/opt/control/etc/status";
open(FH, ">>$file")
or die "Can't open file: $!";

while (<FH>) {
$count++; }
if ($count==31) {
print FH qq[RM="rm2"];}
if ($count==40) {
print FH qq[$RM]
}
if ($count==43) {
print FH qq[rmDESC="Result Manager2"\n];
}
close FH;
exit;
In-place editing of a file isn't easy, even for perl pros. You should either write to a new file, then replace the old file with the new one when done, or load the entire file into a list (array), make your changes, then rewrite it.

Here's the first. There are much better ways to do some of these steps (there are modules for generating temporary names, for example), but I don't want to make it too complex:

Code:
#!/usr/bin/perl

$file    = "/opt/control/etc/status";
$tmpfile = "$file$$";
$RM      = "BLAH";

open($fh1, "<", $file)    or die "Could not open $file:  $!\n";
open($fh2, ">", $tmpfile) or die "Could not open $tmpfile:  $!\n";

$count = 0;
while($line = <$fh1>) {
    $count++;

    $line = "RM=\"rm2\"\n"                 if $count == 31; 
    $line = "$RM\n"                        if $count == 40;
    $line = "rmDESC=\"Result Manager2\"\n" if $count == 43;

    print $fh2 $line;
}

close($fh1);
close($fh2);

system("mv -f \"$tmpfile\" \"$file\"");

And here's how with a list:

Code:
#!/usr/bin/perl

$file = "/opt/control/etc/status";
$RM   = "BLAH";

open($fh, "<", $file) or die "Could not open $file:  $!\n";
@list = <$fh>;
close($fh);

$list[30] = "RM=\"rm2\"\n";
$list[39] = "$RM\n";
$list[42] = "rmDESC=\"Result Manager2\"\n";

open($fh, ">", $file) or die "Could not open $file:  $!\n";
print $fh @list;
close($fh);

Notice how the list elements are 1 less than the lines you wanted to modify. The first element of a list is index 0.

The list solution is shorter, but it's a bad idea to do it this way if the status file is large since it loads the whole file into memory.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

How to enter special characters in a text file using vi?

Hi, I need to create a test text file with the special characters \342\200\223 in it and to be able to use sed maybe to delete them I tried doing it using vi by pressing CTRL-V and then typing 342 but it does not work. After pressing CTRL-V and typing 342 it seems to just insert the numbers... (1 Reply)
Discussion started by: newbie_01
1 Replies

2. UNIX for Dummies Questions & Answers

Search special characters in a file and replace with meaningful text messages like Hello

Search special characters in a file and replace with meaningful text messages like Hello (2 Replies)
Discussion started by: raka_rjit
2 Replies

3. Shell Programming and Scripting

Help with listing file name containing particular text and count of lines with 10 characters.

Hi, I've 2 queries. I need to list files which doesn't contain a particular text in the content. For example say, I need to list files which doesn't contain string "abc" from all files ending with *.bad. How can I do that? Also, I want to display number of lines in a file which has atleast... (2 Replies)
Discussion started by: Gangadhar Reddy
2 Replies

4. Shell Programming and Scripting

Lines starting with special characters

Hi I have a file and need to extract lines starting with "grep ^" I tried with quotes single/double before/after but no luck. suggestion pls, thanks! (2 Replies)
Discussion started by: magnus29
2 Replies

5. Shell Programming and Scripting

Fetch the lines which contains special characters

Hi All, My source file contains special characters(Latin characters).I need to fetch only the lines which contains the special characters. The problem is i don't know which all latin/special characters can come in the source. Is there anyway to extract the lines which contain letters other... (3 Replies)
Discussion started by: joe!!
3 Replies

6. Shell Programming and Scripting

grep lines having special characters

Hi, I have a file which has numerous lines and some of the lines having special characters in it. i want to grep the lines which are having special characters. say, one line looks like - %*()$#@"", | acbd antoher line looks like ***##^%! | efcg so these kind of lines are present... (5 Replies)
Discussion started by: rbalaj16
5 Replies

7. Shell Programming and Scripting

[bash help]Adding multiple lines of text into a specific spot into a text file

I am attempting to insert multiple lines of text into a specific place in a text file based on the lines above or below it. For example, Here is a portion of a zone file. IN NS ns1.domain.tld. IN NS ns2.domain.tld. IN ... (2 Replies)
Discussion started by: cdn_humbucker
2 Replies

8. Shell Programming and Scripting

Remove special characters from text file

Hi All, i am trying to remove all special charecters().,/\~!@#%^$*&^_- and others from a tab delimited file. I am using the following code. while read LINE do echo $LINE | tr -d '=;:`"<>,./?!@#$%^&(){}'|tr -d "-"|tr -d "'" | tr -d "_" done < trial.txt > output.txt Problem ... (10 Replies)
Discussion started by: kkb
10 Replies

9. Shell Programming and Scripting

adding text to a file between lines

Suppose content of my first file: first line second line third line How can i insert text between "first line" & "second Iline" Any help?????/ (7 Replies)
Discussion started by: bishweshwar
7 Replies

10. Shell Programming and Scripting

adding lines at special place in crontab

Hi , i export the crontab in a file (i've no root right) and i would add lines from a file at a special place and rewrite the output in an another file. the special place is as this : 45 04 * * * /home/toto.sh > /dev/null 2>&1 # so i would search for toto.sh and insert the lines , the... (5 Replies)
Discussion started by: Nicol
5 Replies
Login or Register to Ask a Question