19

I have large text files with space delimited strings (2-5). The strings can contain "'" or "-". I'd like to replace say the second space with a pipe.

What's the best way to go?

Using sed I was thinking of this:

sed -r 's/(^[a-z'-]+ [a-z'-]+\b) /\1|/' filename.txt

Any other/better/simpler ideas?

I say Reinstate Monica
  • 25,487
  • 19
  • 95
  • 131
dnkb
  • 387
  • 1
  • 4
  • 11

2 Answers2

26

You can add a number at the end of the substitute command. For example, the following will substitute the second occurrence of old with the string new on each line of file:

sed 's/old/new/2' file

So, instead of your proposed solution, you can use:

sed 's/ /|/2'

For more information, see e.g. this sed tutorial.

mrucci
  • 9,868
  • 3
  • 31
  • 31
  • 2
    From the `sed` info file: *"Note: the POSIX standard does not specify what should happen when you mix the `g' and NUMBER modifiers, and currently there is no widely agreed upon meaning across `sed' implementations. For GNU `sed', the interaction is defined to be: ignore matches before the NUMBERth, and then match and replace all matches from the NUMBERth on."* – Dennis Williamson May 20 '10 at 17:29
  • Info files... I hate them. Anyway, I removed the ambiguous part. Good comment, +1. – mrucci May 20 '10 at 20:52
  • 1
    Thanks, mrucci and Dennis. I thought that there must be something simple out there. – dnkb May 22 '10 at 15:58
  • It seems every problem I have with text manipulation, I manage to solve with `sed`. I'm not sure I should be thanking you for making `sed` even more useful to me, but I will anyway. ;) – Jamie Apr 25 '12 at 15:39
1

Did you try your version? Did it work? Because I think it is basically a good idea. I would do slightly differently, though:

sed -re 's/^([^ ]+ +[^ ]+) /\1|/'

This will accept any characters in a word that is not space, and will accept more than one spaces between the first two words.

petersohn
  • 2,672
  • 3
  • 20
  • 25