Replacing a character string in a file


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Replacing a character string in a file
# 1  
Old 12-07-2005
Replacing a character string in a file

Hi there,
I have a paramater file that looks like this :-

IRL|07122005|27389|VTIEpay|email address|5|200

When my program finishes I want to replace the seventh field. the existing code is like this



cat <<-EOF | ed -s $PARFILE
1,$ g/^$ICO/s/$prvdate/$TODAY/
1,$ g/^$ICO/s/$prvsize/$cursize/
1,$ g/^$ICO/s/$prvamt/$payin/
w $PARFILE
q
EOF


the problem that I'm having is that the code replaces the FIRST instance that of the string i.e. $payin is replacing $prvamt which is the 7th field but it is not - it is replacing the matching string in the third field. I am tearing my hair out.

The file should look like

IRL|07122005|27389|VTIEpay|email address|5|2336590


Can anyone give me a clue what to do ?????
# 2  
Old 12-07-2005
For starters, I wouldn't use ed; I would rather use awk and utilize its considerable power to make changes to this file. You can pass your variables, search for patterns, and manipulate fields rather than whole lines.

For example:

Code:
nawk -F\| -v ICO=IRL -v prvamt=200 -v payin=999 '
    BEGIN {OFS="|"}
    $1 == ICO { 
         if ($7 == prvamt) $7=payin
    }
    1
' $PARFILE

This will make your job much easier.

output:
Code:
IRL|07122005|27389|VTIEpay|email address|5|999

# 3  
Old 12-08-2005
Hi there,
That's great - if I wanted to replace fields 2 and three would the code look like this

$1=ICO {
if ($7 == prvamt) $7=payin,$2=cursize,$3=chksum)
}
1


What is the 1 for .


Thanks for your help
# 4  
Old 12-08-2005
Using awk instead of sed is like using theft to earn money instead of work: perhaps easier to do but coming with a price. In the case of awk the price is performance and size: awk takes a substantially longer time to load compared to sed or ed and does its job at a considerably slower pace.

Both these considerations may or may not be relevant to your problem at hand - if you call awk or sed once you won't notice the difference, if you call it in the middle of a deeply nested loop using sed instead of awk might save a considerable amount of time. Similarly, if your input file is some 100 lines long you won't notice the different speed of operation, if it is a database output with some million of lines to process you might perceive a considerable difference.

Having said this: the real distinguishing point between sed and awk as a text processor is that awk is able to work with a persistent context, whereas seds capabilities in this area are limited to non-existent. If you - for instance - would have to sum one field to a total you would do it with awk (it would be possible to do it with sed, but would be a nightmare - poorly suited tool for the job), in your case it is just a matter of formulating correct regexps and nothing else. I will explain the following solution, which changes two fields (4 and 5) step by step so you can modify it to suit your needs:

Code:
sed '/^'"$ICO"'|/ {
                    s/\(\([^|]*|\)\{3\}\)'"$oldvar1"'/\1'"$newvar1"'/
                    s/\(\([^|]*|\)\{4\}\)'"$oldvar2"'/\1'"$newvar2"'/
                  }'

Your input is organized in fields separated by pipes, so a field is "some non-pipe characters followed by a pipe". The regexp to match such a string is: "[^|]*|". Then there is a construction to "multiply" regexps: "\{<nr>\}", which means "the rexep before <n> times". For instance "a\{5\}" is the same as "aaaaa". I combined these two by grouping the "field regexp" and then multiplying it to match exactly a specific number of fields: "\([^|]*|\)\{3\}" means: "3 fields of non-pipe-chars each followed by a pipe". I grouped this by another "\(...\)" to be able to use it in the replacement string. So, the search string is "three fields followed by the content of oldvar1", which will be replaced by "three fields followed by the content of newvar1". Notice that in oder to change the n-th field we have to mention the first n-1 fields, followed by the search pattern.

This is repeated a second time for the fifth field in my example to show the way of changing multiple fields at once.

At last the surrounding construction: this limits the whole change process to lines with the first field being the content of the shell variable ICO.

At last an observation: the seventh field you wanted to change is the last one in the sample line you provided. This *could* be matched my "[^|]*$", which means "any number of non-pipe characters followed by the end-of-line", but that would imply that your lines can only have seven fields. Using the expressions i supplied there is no such restriction and you can adjust the expression to match any field (save for the first, where the expression becomes simply "^").

Hope this helps.

bakunin
# 5  
Old 12-08-2005
Fantastic post thanks very much for taking the time to write it.

I'm digesting your post now.

thanks
bob...
# 6  
Old 12-08-2005
Quote:
Using awk instead of sed is like using theft to earn money instead of work: perhaps easier to do but coming with a price. In the case of awk the price is performance and size: awk takes a substantially longer time to load compared to sed or ed and does its job at a considerably slower pace.

Both these considerations may or may not be relevant to your problem at hand - if you call awk or sed once you won't notice the difference, if you call it in the middle of a deeply nested loop using sed instead of awk might save a considerable amount of time. Similarly, if your input file is some 100 lines long you won't notice the different speed of operation, if it is a database output with some million of lines to process you might perceive a considerable difference.
Smilie How funny is that? Using theft over legitimate work as an analogy to awk vs. sed. Let's extend that analogy and suggest that he use machine code over C or better, that he use a custom C application rather than a shell script for performance sake Smilie .

[philosophical rambling]
While I agree that unnecessary clock cycles are generally bad when multiplied by being deeply nested in a loop, in my opinion, awk's simplicity coupled with its considerable power simply has more weight especially considering that the OP clearly has to overcome two things: (a) wade through learning counter intuitive UNIX utilities and (b) solving a real business need in light of (a).

Both awk and sed are difficult to grasp at first but I think that awk offers, for your average UNIX user, a simpler path to solving a greater number of text processing problems (whether persistence is necessary or not) for the simple reason that awk can be utilized and understood by a greater number of people; especially those maintaining established code. Constructing moderately complex regular expressions is easier than reading them and remembering what the were supposed to match (at least for me); awk can sometimes insulate you (or a maintainer) from struggling to remember your code. How many people do you know use sed beyond sed 's/search/replace/' or awk beyond awk '{print $4}'? I still find people who have years of UNIX experience creating the ugliest grep filter pipes imaginable on a per line basis. In all of my years working in many different shops, I don't find too many people who go very far beyond these examples.
[/philosophical rambling]

Quote:
if I wanted to replace fields 2 and three would the code look like this

$1=ICO {
if ($7 == prvamt) $7=payin,$2=cursize,$3=chksum)
}
1

What is the 1 for .
The answer to your first question is “that depends.” If $2 and $3 should be changed based on $7's evaluation, then yes. awk's syntax is like C so your statement would be written like this (notice the curly braces):
Code:
if ($7 == prvamt) {
    $7=payin
    $2=cursize
    $3=chksum
}

The answer to your second question is more complicated. An awk script is comprised of autonomous procedures that function on essentially lines of input. My example consists of two autonomous procedures, one that tests whether the current input line has field seven ($7) matching the variable that I passed in "prvamt". The second procedure (the 1 by itself) is very misleading and I should not have used it for your benefit. Each autonomous procedure can result in a 0 or non 0 result and, in my constant non 0 result, I am telling awk to effectively print the modified line of input (changed by my first procedure where $1 was tested against ICO). I should have written it as this:
Code:
nawk -F\| -v ICO=IRL -v prvamt=200 -v payin=999 '
    BEGIN {OFS="|"}
    $1 == ICO { 
         if ($7 == prvamt) {
             $7=payin
         }
    }
    { print }
' $PARFILE

I hope this helps and, by all means, write it in machine code if you want performance gains over shell scipting. Smilie

Seriously though, bakunin's comments have merit and there are applications for both; you'll want to learn both utilities. Certainly there are many ways to achieve your goal and neither sed nor awk are your only choices. Many people prefer perl to solve these kinds of problems and some ever prefer ruby, which seems less intuitive. I don't write many perl scripts since I haven't been limited by sed or awk as yet.

Last edited by tmarikle; 12-08-2005 at 02:18 PM..
# 7  
Old 12-09-2005
Hi tmarikle,
thanks for your help
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Replacing string values from a File

I want to replace string values from a file to a file For eg : File1 has 30 lines of string with values, those specific values needs to be changed in file2 and remaining values in file2 should be as it is. For example: From file (File1) cluster.name=secondaryCluster To replace File... (9 Replies)
Discussion started by: sriram003
9 Replies

2. Programming

Need help for replacing a string in a text file at runtime !

Hi All, I am facing an issue... I need to replace some string in a text file while the same file is read by some other user at the same time. The other user is using it in the Read only mode. So I can't create a temporary file and write the content first and then write it back into the original... (2 Replies)
Discussion started by: agupta2
2 Replies

3. UNIX for Dummies Questions & Answers

replacing a string with another string in a txt file

Dear all, I have a file like below. I want to replace all the '.' in the 3rd column with 'NA'. I don't know how to do that. Anyone has an iead? Thanks a lot! 8 70003200 21.6206 9 70005700 17.5064 10 70002200 . 11 70005100 19.1001 17 70008000 16.1970 32 70012400 26.3465 33... (9 Replies)
Discussion started by: forevertl
9 Replies

4. Shell Programming and Scripting

Renaming a file and replacing the special character in the name with date

HI all, How can i rename some files and replace the special character in the name with todays date ex: Name#file1.txt Name#file2.txt to be renamed as Name.20091119.file1.txt Name.20091119.file2.txt (11 Replies)
Discussion started by: abhinav192
11 Replies

5. Shell Programming and Scripting

Replacing Character in a file based on element

Hi, I have file like below. Unix:/pclls/turc>cat tibc.property executeReceiver=Y executeSender=Y I want to replace executeSender=N in the file. My file should be like below. executeReceiver=Y executeSender=N I tried with the below command, its giving error. cat tibc.property |... (2 Replies)
Discussion started by: senthil_is
2 Replies

6. Shell Programming and Scripting

Replacing the last character for each line in a file

Hello, I have a csv file and will like to replace the last character of each line in the file with Z (20 Replies)
Discussion started by: 123script
20 Replies

7. Shell Programming and Scripting

error while replacing a string by new line character in sed

hi, when i am doing the following things getting error Can anyone please suggest i have a file where there is a line like the following branch=dev sdf dev jin kilii fin kale boyle dev james dev i want to search the existance of dev in the above line. cat "$file" | sed -n... (8 Replies)
Discussion started by: millan
8 Replies

8. Shell Programming and Scripting

replacing string in an XML file

Hi all, I need to replace string in XML file..XML file like <dependency> <groupId>fr.orange.portail.ear</groupId> <artifactId>_AdminServicesEAR</artifactId> <version>1.0.0-20080521.085352-1</version> <type>ear</type> </dependency> <dependency> ... (2 Replies)
Discussion started by: subin_bala
2 Replies

9. Shell Programming and Scripting

replacing string with special character ???

the problem is while replacing the old string with new one with the help of SED i am unable to replace the special characters with new strings. how can i do that? i dont want the user to be given the trouble to write '\' before every special characters like * , . , \ , $ , &. sed... (4 Replies)
Discussion started by: imppayel
4 Replies
Login or Register to Ask a Question