2016-06-30 4 views
-1

Lassen Sie uns sagen, dass ich eine Datei (example.txt) mit der nächsten Struktur:aber nicht alle Felder in Textdatei (Shell/bash)

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

Ich möchte die Räume zwischen den ersetzen Zahlen mit einem Trennzeichen, wie | oder ,, aber nicht den Namen beeinflussen.

Eine Option, die ich dachte, ist, den Platz im Namen zu ändern und einen "niedrigen Balken" zu setzen, dann alle Leerzeichen in der Datei zu entfernen und "|" und nach dem Ändern wieder das "_" im Namen für ein Leerzeichen.

Irgendeine Idee, wie man das in der Shell macht? Oder vielleicht eine bessere Option?

Der erwarten Ausgang wäre dies

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!

+0

ich es –

+0

jetzt aktualisiert haben Sie die erwartete Ausgabe zeigt, nachdem der alle Räume haben Name ersetzt durch eine Pipe '|' und der einzige _code_, den ich in diesem ganzen Thread sehe, der das tut, was Sie sagen wollen, ist derjenige, der von andlrc geschrieben wurde. Der von Chris Maes und Ihnen als Kommentar zu seiner Antwort geschriebene Text liefert nicht die erwartete Ausgabe, wie in der Frage angegeben! Warum also wird eine Antwort, die nicht die erwartete Ausgabe produziert, als die beste Antwort markiert und auch gewählt. Die Antwort von andlrc ist diejenige, die als beste Antwort und auch als beste Antwort markiert werden sollte, da sie schließlich die definierte erwartete Ausgabe produziert. – user3439894

+0

Ich habe die Antwort 'sed -i' s/\ ([[: digit:]] \) \ \ ([[: digit:]] \)/\ 1 | \ 2/g 'datei.txt' verwendet plus 'sed -i 's/\ ([[: oben:]] \) \ \ ([[: digit:]] \)/\ 1 | \ 2/g'' und es funktioniert mit meiner Datei. Vielleicht ist etwas, was ich vermisse, weil ich nicht viel über Shell weiß, aber es funktioniert –

Antwort

2

Sie können alle Leerzeichen gefolgt von einer Ziffer ersetzen:

$ 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 

Aufteilung:

s/      / /g # Global substitute command 
    [[:space:]]      # Match a space 
       [[:digit:]]   # Match a digit 
      \(   \)  # Capture in \1 
           |\1 # Replace with | and captured digit 
+0

Ok! Danke vielmals! Ich denke, es wird funktionieren. –

+0

Aber wenn anstelle von NAME1 mit der Nummer nur NAME ist, was soll ich anstelle von "digit" schreiben? –

+0

Ich habe die Frage geändert, weil die Zahlen am Ende der Frage nicht notwendig sind –

1

können Sie einen sed Ausdruck verwenden, das zu tun:

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

Ausgang:

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

Erklärung des sed Befehl:

  • -i: in-place: ändern Datei .txt
  • [[: digit:]]: wie Sie vielleicht denken: eine Ziffer
  • \(<patter>\): etwas zwischen entkam Klammern \( und \) macht sie zu einem Muster umschließt, auf die verwiesen werden kann. Da ich das zweimal benutzt habe; im zweiten Teil des sed-Befehls; Ich kann \1 und \2 verwenden, um auf diese zwei Muster zu verweisen.
+2

Soll 'NAME4 | 1 5 | 8' kein' '' '' '' zwischen '1' und' 5' haben? – user3439894

+0

Ja, sollte es. Irgendwie vielen Dank, ich habe die Idee. Ich werde es jetzt versuchen –

+0

Ich habe die Frage geändert, weil nicht erforderlich ist Zahlen am Ende der Frage –

Verwandte Themen