4

The code below replaces the first occurrence of apple with banana. How do I achieve the same using awk / gawk?

sed -i "0,/apple/s//banana/" myfile.txt
Santosh Pillai
  • 1,311
  • 1
  • 20
  • 31

1 Answers1

8

this is what I come up with:

awk '!x{x=sub("apple","banana")}7' file

for example:

kent$  cat f
foo
apple
foo
apple
apple

kent$  awk '!x{x=sub("apple","banana")}7' f
foo
banana
foo
apple
apple

for the sed -i (change in place) part, if you use gawk 4.1.0, you have that option too. otherwise, you have to use a temp file.

Kent
  • 189,393
  • 32
  • 233
  • 301
  • you are using the `7`. That's funny! :) +1 – hek2mgl Aug 12 '13 at 21:27
  • @hek2mgl if I used `1`, you could `+1`, now I used `7`, you should `+7` :) no special reason, I like that number.. – Kent Aug 12 '13 at 21:29
  • never seen this before. but of course any number except of `0` is valid.. like `awk` so much!! but if you ask me `sed` is more appropriate here. (that's why I gave that answer)... – hek2mgl Aug 12 '13 at 21:30
  • @hek2mgl No. try `-1` – Kent Aug 12 '13 at 21:32
  • thx. was about about to try just in this moment :) ... yes, that's a useful information – hek2mgl Aug 12 '13 at 21:33
  • @hek2mgl if there was only `-1`, like `awk '-1' file`, it could have problem. – Kent Aug 12 '13 at 21:36
  • @Kent I am using gawk for windows. I am seeing this error.gawk: fatal: `!x{x' is not a legal variable name. My one liner is gawk -v "!x{x=sub("apple","banana")}7" myfile.txt > tempfile.txt – Santosh Pillai Aug 12 '13 at 21:40
  • No I meant just: `awk '-1' file` (It prints the usage information).... Btw, `on Windows` : I offer my condolence. Have installed a windows7 home network for friends the whole (last 3) days... grrrrrr.. ;) – hek2mgl Aug 12 '13 at 21:42
  • @SantoshPillai I never tried awk in windows, don't know the difference. can you try `awk '{if(x==0)x=sub(/foo/,"bar")}7' file` – Kent Aug 12 '13 at 21:44
  • hey @SantoshPillai I just read your comment carefully, why you have a `-v` ? remove it and try. – Kent Aug 12 '13 at 21:46
  • @kent gawk: fatal: `{if(x' is not a legal variable name – Santosh Pillai Aug 12 '13 at 21:48
  • @SantoshPillai did you remove the `-v` ? – Kent Aug 12 '13 at 21:54
  • yes, now i dont see any errors. but there are no replacements done :( – Santosh Pillai Aug 12 '13 at 22:02
  • You just nerd-sniped me, but I managed to figure out what the hell that `7` was at the end. It's only a truey thing acting as a second instruction, which is an implicit `print $0`, isn't it? You bastards. I love it. – matega Jun 27 '15 at 18:58
  • What is that 7 number? I tried some numbers, they all worked except 0. Would you explain the whole command with details please? – Mohammed Noureldin Aug 28 '17 at 00:43
  • 1
    @MohammedNoureldin because non-zero number does default action in awk: print – Kent Aug 28 '17 at 08:16
  • So what is the difference between using 7, 777 or -1?. Actually I still new to AWK, would you recommend any reference which explain the syntax you wrote? I tried yesterday to find something helpful with no success. Or maybe any keyword to search for? (except `AWK` keyword ;)) – Mohammed Noureldin Aug 28 '17 at 08:18
  • 1
    @MohammedNoureldin no difference. I prefer right index finger, so I picked 7 – Kent Aug 28 '17 at 08:33
  • 4
    OK to help the others, another form of the command to make it more readable: `awk '!x{x=sub("apple","banana")}{print $0}' test`. substituting {print} with a number (any thing other than 0 is true), makes {print} to be true (even is not written). This syntax `!x{...}` means: if x != false (i.e. if it has a value) do something. The rest should be clear for any essential knowledge programmer. – Mohammed Noureldin Aug 28 '17 at 09:52