Replace second match+awk/sed


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Replace second match+awk/sed
# 1  
Old 11-22-2013
Question Replace second match+awk/sed

I have a text file that looks like this:
Code:
-----------------------------------------
sta WP00 
time 10/23/2013 20:10:17
sensor trillium_240_2 0 583
add
close sensor trillium_240_2 10/23/2013 20:10:17

sensor trillium_120 0 279
add
close sensor trillium_120 10/23/2013 20:10:35
---------------------------------------------
sta WP00
time 10/28/2013 20:20:28
sensor trillium_240_2 0 583
add
close sensor trillium_240_2 10/28/2013 20:20:28

sensor trillium_120 0 268
add
close sensor trillium_120 10/28/2013 20:20:45
----------------------------------------------

I've added in the lines to make it clear where one entry begins and the other ends but they are not in the original text file.

What I want to do for each station (in this example WP00) is to grab every second match of time value and replace that second match date and time with the close date and time from the two previous entries. Make sense?

To put this more explicitly I would like to loop over my stations (only one shown in the example) and grab out every second time match, in this example that would be the line:

time 10/28/2013 20:20:28

I want to use the date and time (10/28/2013 20:20:28) to replace the date and time from the two close statements before it:

Code:
close sensor trillium_240_2 10/23/2013 20:10:17 
close sensor trillium_120 10/23/2013 20:10:35

so that for this example they would read:

Code:
close sensor trillium_240_2 10/28/2013 20:20:28 
close sensor trillium_120 10/28/2013 20:20:28

I have fiddled with this for a few days trying to get it to work but can't seem to get something right. Right now I can grab out every second match of time with awk using:

awk '/time/ && !(++c%2)' file.txt

But wasn't sure the best way thereafter to go about replacing those values with the close statements. Remember I want to loop over the stations too so only the time values of the same stations are associated with each other.

I also tried:
awk 'NR==FNR{ if(/^close/){i++ if(i<3)a[NR]=$1FS$2FS$3 if(i==3) for(x in a) a[x]=a[x]FS$4FS$5 l=NR } next } FNR in a{$0=a[FNR]} FNR==l{$0=$1FS$2FS$3FS"12/31/2500 23:59:59"}7' file file

But I would really like to use csh and this only works for the first
entry not all of them.

I'm at a loss of what to do, can anyone give me any ideas of how to do this?

Thanks in advance and sorry for the long-windedness Smilie

Moderator's Comments:
Mod Comment Code tags for code please.

Last edited by Corona688; 11-22-2013 at 05:10 PM..
# 2  
Old 11-22-2013
If I understand correctly... You want to move all dates 'up'? The dates for entry 3 go into entry 2, the dates for entry 2 go into entry 1, etc? I can certainly understand why you're finding it so difficult to go back in time and reprocess lines you've already processed. When you need to look backwards like that, I would scan the file twice:

Code:
awk 'NR==FNR { first pass code ; next } { second pass code ; print }' inputfile inputfile

Note how inputfile is given twice. The first time the file is read, it goes into the { first pass code } block, where you can save whatever information you need. The second time it reads the file, it goes into { second pass code } where you can do the substituting and printing.
# 3  
Old 11-22-2013
What I want to do is take the second matched time entry, in this case

Code:
time 10/28/2013 20:20:28

and insert the date and time for the 2 previous close statements so instead of reading:

Code:
close sensor trillium_240_2 10/23/2013 20:10:17  
close sensor trillium_120 10/23/2013 20:10:35

They read:

Code:
close sensor trillium_240_2 10/28/2013 20:20:28 
 close sensor trillium_120 10/28/2013 20:20:28

I want to use the time from the second station entry and put it in the close statement of the first station entries, does that make more sense? So the dates for entry 3 go into close date entries for 2 and 1. And if there was a date for entry 6 it would go into the close date/time for entries 5 and 4.

Scanning the file twice was why I tried the awk 'NR==FNR entry but I could only get it to work on the first entry and then it would quit. Any ideas how to modify it to get it to work in a loop or a piece of code that works to do this?

Last edited by Scrutinizer; 11-23-2013 at 03:37 AM.. Reason: code tags
# 4  
Old 11-22-2013
Hmm, I think I might be beginning to get it:

Code:
awk '
# Store all time entries
NR==FNR && /time/ { A[++N]=$2" "$3 ; next }
/time/ { M++ } # Count entry number in second pass
# Truncate line to close sensor trillium_240_2, and add new date to end
((M%2) == 0) && /close/ { NF=3; $0=$0" "A[M+1] } 1' inputfile inputfile

# 5  
Old 11-22-2013
Hmm...that doesn't seem to work, they are left unchanged in the first entry and stripped off of the second entry. I'm trying to think about how to maybe modify what you just put:

What I want the text file to look like is, it starts out like this:

Code:
sta WP00 
 time 10/23/2013 20:10:17 
sensor trillium_240_2 0 583 
add 
close sensor trillium_240_2 10/23/2013 20:10:17  

sensor trillium_120 0 279 
add 
close sensor trillium_120 10/23/2013 20:10:35
 --------------------------------------------- 
sta WP00
 time 10/28/2013 20:20:28
 sensor trillium_240_2 0 583
 add 
close sensor trillium_240_2 10/28/2013 20:20:28  

sensor trillium_120 0 268 
add 
close sensor trillium_120 10/28/2013 20:20:45

and I want it to transform to this (for each station):

Code:
sta WP00 
 time 10/23/2013 20:10:17 
sensor trillium_240_2 0 583 
add 
close sensor trillium_240_2 10/28/2013 20:20:28  

sensor trillium_120 0 279 
add
 close sensor trillium_120 10/28/2013 20:20:28
 --------------------------------------------- 
sta WP00 
time 10/28/2013 20:20:28 
sensor trillium_240_2 0 583 
add 
close sensor trillium_240_2 10/28/2013 20:20:28 

sensor trillium_120 0 268 
add
 close sensor trillium_120 10/28/2013 20:20:45

Is that more clear?

---------- Post updated at 02:56 PM ---------- Previous update was at 02:39 PM ----------

Your code is actually doing this to the file:

Code:
sta WP00 
time 10/23/2013 20:10:17
sensor trillium_240_2 0 583
add
close sensor trillium_240_2 10/23/2013 20:10:17

sensor trillium_120 0 279
add
close sensor trillium_120 10/23/2013 20:10:35
---------------------------------------------
sta WP00
time 10/28/2013 20:20:28
sensor trillium_240_2 0 583
add
close sensor trillium_240_2 10/23/2013 20:10:17

sensor trillium_120 0 268
add
close sensor trillium_120 10/23/2013 20:10:17


Last edited by Corona688; 11-22-2013 at 05:51 PM..
# 6  
Old 11-22-2013
With a complete set of data to test on I found the error I think, it wasn't doing {next } for all lines in the first file, just the ones with time in them.

Code:
awk 'NR==FNR && /time/               {       A[++N]=$2" "$3  }
NR==FNR                         {       next            }
/time/                          {       M++             }
M && ((M%2) == 1) && /close/ {  NF=3 ; $0=$0" "A[M+1]   } 1' inputfile inputfile

This User Gave Thanks to Corona688 For This Post:
# 7  
Old 11-22-2013
Not sure if this is faster than above proposal:
Code:
tac file | awk '/time/ {X=$NF}  /close/ && X {$NF=X}  1 '| tac
sta WP00 
 time 10/23/2013 20:10:17 
sensor trillium_240_2 0 583 
add 
close sensor trillium_240_2 10/23/2013 20:20:28

sensor trillium_120 0 279 
add 
close sensor trillium_120 10/23/2013 20:20:28
 --------------------------------------------- 
sta WP00
 time 10/28/2013 20:20:28
 sensor trillium_240_2 0 583
 add 
close sensor trillium_240_2 10/28/2013 20:20:28  

sensor trillium_120 0 268 
add 
close sensor trillium_120 10/28/2013 20:20:45

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Pattern match and replace indirect directory reference using sed

Hi, I need a ksh script to replace indirect directory references in an .ini file with a env variable using sed or awk. The .ini file is for example as such: A=.. B=../ C=../.. D=../../ E=../bin F=../../bin G=../../bin/xml H=../../bin/xml/ Need to replace an instance of .. or... (2 Replies)
Discussion started by: andyatit
2 Replies

2. Shell Programming and Scripting

sed : replace Nth match in a file

I have a situation where a file "config.txt" looks like this Servername: OS: Serername: OS: Servername: OS: .... .... ... Servername: OS: looking for the sed syntax to replace the "Nth" occurrence of Servername (i would apply the same logic to OS as well), want to replace the Nth... (4 Replies)
Discussion started by: alldbest
4 Replies

3. Shell Programming and Scripting

Need help with sed to match and replace a string

friends I am struck in a situation where I need to comment a line start with space as below in a file root@LOCALHOST * rw LOCALHOST* r I should comment second line only Any help please (16 Replies)
Discussion started by: mallak
16 Replies

4. Shell Programming and Scripting

awk Match First Field and Replace Second Column

Hi Friends, I have looked around the forums and over online but couldn't figure out how to deal with this problem input.txt gene1,axis1/0/1,axis2/0/1 gene1,axis1/1/2,axis2/1/2 gene1,axis1/2/3,axis2/2/3 gene2,axis1/3/4,axis2/3/4 Match on first column and if first column is... (1 Reply)
Discussion started by: jacobs.smith
1 Replies

5. Shell Programming and Scripting

sed Character match and replace

Hello All I am struck in the issue which I want to share with all of you. What I am trying to do is For every line in a file I have to replace a particular character from the given character in a file For Example Suppose the data is 1111x2222 1111x2222 2222y3333 1111x2222 I... (4 Replies)
Discussion started by: adisky123
4 Replies

6. UNIX for Dummies Questions & Answers

awk/sed match and extraction

Hi, I have a file like this- aa 12 23 34 aa 21 34 56 aa 78 45 56 I want to print out only the lines after the last aa. How do I do this? I tried using grep -A and sed -n, but both didnt work as I wanted to. Could someone help me out please.. (3 Replies)
Discussion started by: jamie_123
3 Replies

7. Shell Programming and Scripting

Match a Pattern & Replace The value Using AWK

I have a csv file in which i have to search a particular string and replace the data in any column with something else. How do i do it using awk. file ------ 2001,John,USA,MN,20101001,29091.50,M,Active,Y 2002,Mike,USA,NY,20090130,342.00,M,Pending,N... (3 Replies)
Discussion started by: Sheel
3 Replies

8. Shell Programming and Scripting

Match and replace value in 2 different places using awk

Hi, I need help on replacing values in certain field in my file1.txt based on matched patterns in file2.txt using awk. The blue color need to match with one of the data in field $2 in file2.txt. If match, BEGIN and FINISHED value in red will have a new value from field $3 and $4 accordingly.... (3 Replies)
Discussion started by: redse171
3 Replies

9. Shell Programming and Scripting

SED to replace exact match, not first occurrence.

Lets say I have file.txt: (Product:Price:QuantityAvailable) (: as delimiter) Chocolate:5:5 Banana:33:3 I am doing a edit/update function. I want to change the Quantity Available, so I tried using the SED command to replace 5, but my Price which is also 5 is changed instead. (for the Banana... (13 Replies)
Discussion started by: andylbh
13 Replies

10. Shell Programming and Scripting

Sed scripting, match text within line and replace

New to sed... Have a file foo.txt (below). Need to replace text on 2 lines, but can only feed sed the first few characters of each line (all lines are unique). So, in my example, I have put '$' in place of what I need to figure out how to feed the whole line. What I have thus far: sed -e... (6 Replies)
Discussion started by: boolean2222
6 Replies
Login or Register to Ask a Question