-1

Let's say that I have a file (example.txt) with the next structure:

NAAME 111 2222 333
NAMME 111 22 333 
NNA ME 444 555 2
NNAAME 1 5 8
N MEEE 44 66 111

I would like to replace the spaces between the numbers with a separator, like | or , but not affecting the name.

One option I was thinking is to change the space in the name and put a "low bar", then remove all the spaces in the file and write "|" and after change again the "_" in the name for a space.

Any idea how to do that in shell? Or maybe a better option?

The expect output would be this

NAAME|111|2222|333
NAMME|111|22|333 
NNA ME|444|555|2
NNAAME|1|5|8
N MEEE|44|66|111

Thank you very much!

  • I've updated it now – Alfonso Ventanova Jun 30 '16 at 10:19
  • You are showing the expected output to have all spaces after the name replaced with a pipe `|` and the only _code_ I see in this entire thread that does what you're saying you want is the one written by andlrc. The one written by Chris Maes and your's as a comment to his answer does not produce the expected output as stated in the question! So why is an answer that doesn't produce the expected output marked as the best answer and up voted too. andlrc's answer is the one that should be marked as the best answer and up voted too, as it does after all produce the defined expected output. – user3439894 Jun 30 '16 at 12:11
  • I've used the answer `sed -i 's/\([[:digit:]]\)\ \([[:digit:]]\)/\1|\2/g' file.txt` plus `sed -i 's/\([[:upper:]]\)\ \([[:digit:]]\)/\1|\2/g'` and it works in with my file. Maybe is something that I'm missing because I don't know much about shell but it works – Alfonso Ventanova Jun 30 '16 at 13:15
  • Before you edited your original question Chris Maes's answer left a space between `1` and `5`, e.g. `NAME4|1 5|8` and therefore his answer is wrong. With your edit it leaves a space between `5` and `8`, e.g. `NNAAME|1|5 8` and adding your `sed` command changes nothing! His along with what you added it's still not producing the expected results as stated in your question and so it still wrong! Only andlrc's answer is doing as requested, replace all spaces with a pipe `|` after the name. Do you understand it now!? – user3439894 Jun 30 '16 at 13:56
  • Ok yes! excuse me. I forgot that there is a space between 1 and 5. – Alfonso Ventanova Jun 30 '16 at 14:22
  • Anyway, in my case with names without numbers and then only numbers I've used: `sed -i 's/\([[:digit:]]\)\ \([[:digit:]]\)/\1|\2/g' file.txt` to eliminate the space between the numbers and insert a "|". It's true that the file is too big and it didn't change all at first, but I copy and paste the code in the script and it works nice with 2 tries! Probably is not the best way, I know. Then, to remove the space between the NAME and the first number I've used this: `sed -i 's/\([[:upper:]]\)\ \([[:digit:]]\)/\1|\2/g'`. – Alfonso Ventanova Jun 30 '16 at 14:39

2 Answers2

2

You can replace all spaces followed by a digit:

$ sed 's/[[:space:]]\([[:digit:]]\)/|\1/g' file
NAME1|111|2222|333
NAME2|111|22|333 
NA ME3|444|555|2
NAME4|1|5|8
N ME5|44|66|111

Breakdown:

s/                          /   /g # Global substitute command
  [[:space:]]                      # Match a space
               [[:digit:]]         # Match a digit
             \(           \)       # Capture in \1
                              |\1  # Replace with | and captured digit
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
1

you can use a sed expression to do that:

sed -i 's/\([[:digit:]]\)\ \([[:digit:]]\)/\1|\2/g' file.txt

output:

NAME1|111|2222|333
NAME2|111|22|333
NA ME3|444|555|2
NAME4|1 5|8
N ME5|44|66|111

explanation of the sed command:

  • -i : in-place: modify file.txt
  • [[:digit:]] : as you might think: matches a digit
  • \(<patter>\) : enclosing something between escaped brackets \( and \) makes them a pattern that can be referenced. Since I used this twice; in the second part of the sed command; I can use \1 and \2 to refer to these two patterns.
Chris Maes
  • 35,025
  • 12
  • 111
  • 136