2

I have a file in which I am trying to change two strings or trying to swapping with each other..

cat filename| grep m07

filesystem special="/abc/ca97" raw="/abc/ca97" directory="/mount/m07" 
filesystem special="/abc/d1107" raw="/abc/d1107" directory="/m07"

so I am trying to swap /mount/m07 with /m07 so that required output should be after operation:

filesystem special="/abc/ca97" raw="/abc/ca97" directory="/m07"
filesystem special="/abc/d1107" raw="/abc/d1107" directory="/mount/m07"

I tried it with using sed..

sed -e 's/"\/mount\/m07/"\m07/g' -e 's/"\/m07/"\/mount/\/m07' file_name

and

sed -e 's/"\/m07/"\/mount/\/m07' -e 's/"\/mount\/m07/"\m07/g' file_name

But in both the cases its replacing both the strings so either I get /mount/m07 or /m07 in both of the lines...

could you please suggest the path to reach the desired output...

Sandy
  • 419
  • 1
  • 8
  • 15

3 Answers3

4

Simple sed will do the task for you.

sed '/m07/s#/mount/m07#/m07#;t;/m07/s#/m07#/mount/m07#'    Input_file

For Input_file you mentioned or command's output, following will be the output:

your_command | sed '/m07/s#/mount/m07#/m07#;n;/m07/s#/m07#/mount/m07#' 
<filesystem special="/abc/ca97" raw="/abc/ca97" directory="/m07" >
<filesystem special="/abc/d1107" raw="/abc/d1107" directory="/m07">

EDIT: Adding explanation too now for above command, THANKS to Sundeep for letting me know that t option is better than n. Also following code is only for explanation purposes not for running.

sed '/m07/                    Searching for string m07 in a line, if it is present then only do substitutions in that line.
s#/mount/m07#/m07#;           Doing substitution here substitute /mount/m07 with m07 here
t;                            t is for(from man sed page) If  a s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label if label is omitted, branch to end of script.
/m07/s#/m07#/mount/m07#       searching string m07 and then substitute string /m07 with /mount/m07
'    Input_file               Mentioning Input_file.
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • 1
    @User123, in `sed` we could create our own separators too eg--> `sed '/m07/s@/mount/m07@/m07@' Input_file`. – RavinderSingh13 Jan 19 '18 at 15:36
  • 2
    looks like everybody missed the question - it says swap... so `/mount/m07` is changed to `/m07` and `/m07` is changed to `/mount/m07` – Sundeep Jan 19 '18 at 15:39
  • well, i tried the command you mentioned but it showing /m07 in both lines, whereas I am trying to swap them to get this output.. filesystem special="/abc/ca97" raw="/abc/ca97" directory="/m07" filesystem special="/abc/d1107" raw="/abc/d1107" directory="/mount/m07" – Sandy Jan 19 '18 at 15:40
  • 2
    @RavinderSingh13 using `n` will work for given example, but not a generic solution.. just add a line in between given sample and you'll see – Sundeep Jan 19 '18 at 15:47
  • @Sundeep, thanks a TON sir for letting know here, changed it in code. – RavinderSingh13 Jan 19 '18 at 17:32
  • 1
    @RavinderSingh13: thanks Ravinder for the explanation.. :) – Sandy Jan 22 '18 at 10:01
2

question is tagged linux, so am assuming GNU sed is available (not sure if below solution is POSIX). also assuming that both the strings are not present in same line

$ sed 's#/mount/m07#/m07#; t; s#/m07#/mount/m07#' ip.txt
filesystem special="/abc/ca97" raw="/abc/ca97" directory="/m07" 
filesystem special="/abc/d1107" raw="/abc/d1107" directory="/mount/m07"
  • t command will branch to specified label on successful substitution
  • Without label, t will skip rest of commands and start next cycle
  • so, if s#/mount/m07#/m07# succeeds, t command will tell sed to skip rest of commands and read next line for processing
  • but if the first substitution doesn't succeed, then the second substitution would be attempted

for non-GNU versions - thanks @anubhava

sed -e 's#/mount/m07#/m07#;t' -e 's#/m07#/mount/m07#'
#or
sed -e 's#/mount/m07#/m07#' -e 't' -e 's#/m07#/mount/m07#'

Further Reading

Sundeep
  • 23,246
  • 2
  • 28
  • 103
0
$ cat sedswap.txt 
/mount/m07
/m07

$ sed -e 's/\/mount\/m07/\/rm07/g' -e 's/\/m07/\/mount\/m07/g' -e 's/\/rm07/\/m07/g' sedswap.txt
/m07
/mount/m07

Basically using a temp variable approach

SouravP
  • 1
  • 2
  • Or like others previously have mentioned use a custom delimiter in sed `$ sed -e 's#/mount/m07#/rm07#g' -e 's#/m07#/mount/m07#g' -e 's#/rm07#/m07#g' sedswap.txt` – SouravP Jan 19 '18 at 16:23