3

Hi I have a file which has lines as below ( below is a single sample line)

Running Test File: 
/home/rsc_app|06_2BIN/08_payfacil/01_5BIN/003_nt2bnet_Acq004601_0100_0420_mc.utt|Test
Result | Pass | MIG_NT2_EP2 CIS_EP1|0403319|

what i am trying to achieve is match the

/003_nt2bnet_Acq004601_0100_0420_mc.utt

and change the / as | so the outcome to be ( the text before .UTT can be anything basically it is a file name and .utt is the extension so i want to find the pattern to match .utt and replace the / to |)

|003_nt2bnet_Acq004601_0100_0420_mc.utt

the whole line to be

Running Test File:
/home/rsc_app|06_2BIN/08_payfacil/01_5BIN|003_nt2bnet_Acq004601_0100_0420_mc.utt|Test
Result | Pass | MIG_NT2_EP2 CIS_EP1|0403319|

I have tried so many regexp to match but not able to do so . the last one which I tried was as below

awk -F["|"] '{if($3~/\/.+?(?=utt)/){sub(/\//,"|",$0)}} {print $0}'

any help would be greatly appreciated.

Abrar Ahamed
  • 199
  • 11
  • 1
    also note that lookarounds are not supported by awk.. see also: https://unix.stackexchange.com/questions/119905/why-does-my-regular-expression-work-in-x-but-not-in-y – Sundeep Feb 17 '18 at 08:22

3 Answers3

4

Try

sed 's#/\([^/]*\.utt\)#|\1#'

This will match a / followed by non-/ characters ending with .utt (except the first /, rest are captured in a group to be backreferenced in replacement section)

Note that this doesn't specifically restrict the matching to 3rd field

Sundeep
  • 23,246
  • 2
  • 28
  • 103
1

Following awk may also help you on same(considering your Input_file is same as shown sample):

awk 'match($0,/\/003_nt2bnet_Acq004601_0100_0420_mc.utt/){print substr($0,1,RSTART-1) "|" substr($0,RSTART+1,1) substr($0,RSTART+2);next} 1'  Input_file

Adding a non-one liner form of solution too now:

awk '
{
   if(match($0,/\/003_nt2bnet_Acq004601_0100_0420_mc.utt/)){
     print substr($0,1,RSTART-1) "|" substr($0,RSTART+1,1) substr($0,RSTART+2);
     next}
}
1
'   Input_file

OR

awk '
match($0,/\/003_nt2bnet_Acq004601_0100_0420_mc.utt/){
     print substr($0,1,RSTART-1) "|" substr($0,RSTART+1,1) substr($0,RSTART+2);
     next}
1
'  Input_file
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
1

Use rev to reverse the text and replace the first / with |. Using awk:

$ rev file | 
  awk '{sub(/\//,"|")}1' | 
  rev
/home/rsc_app|06_2BIN/08_payfacil/01_5BIN|003_nt2bnet_Acq004601_0100_0420_mc.utt|Test
Result | Pass | MIG_NT2_EP2 CIS_EP1|0403319|

This makes change on every record so if there are /s in other records, use some exclusion rule.

Edit: On Sundeep's comment, using GNU awk's gensub and greediness:

$ awk '{$0=gensub(/(.*)\//,"\\1|",$0)}1' file
James Brown
  • 36,089
  • 7
  • 43
  • 59
  • 1
    replacing last occurrence of something is possible with regex too, taking advantage of greediness... `echo 'a/b/c/d/e' | sed 's#\(.*\)/#\1|#'` – Sundeep Feb 17 '18 at 09:12