So ersetzen Sie ein Zeichen in einem Intervall, das durch zwei andere Zeichen aus einer Datei begrenzt wird

535
Anand

Ich muss alle Vorkommen des vertikalen Strichzeichens |durch ein Komma ersetzen, ,wenn sie zwischen [und ]Zeichen in jeder Zeile einer Datei stehen.

Nehmen wir an, ich habe die folgende Zeichenfolge in der Datei:

wah wah| [go great|no great|so great] | wah wah | [go great|no great|so great] 

Ich möchte, dass meine Ausgabe wie folgt aussieht:

wah wah| [go great,no great,so great] | wah wah | [go great,no great,so great] 

Beachten Sie, dass es mehrere [... ]Paare geben kann. Vertikale Balken zwischen dem ersten ]und dem zweiten [sollten nicht geändert werden.

Wie kann ich dies mit Shell-Befehlen erreichen? Ich habe mehrere Möglichkeiten ausprobiert, aber nichts hat funktioniert.

sed '/[/,/]/s/|/,/g' abcd.csv 
0

1 Antwort auf die Frage

2
Scott

Tun

sed ': Schleife; s / \ (\ [[^] [] * \) | \ ([^] [] * \] \) / \ 1, \ 2 /; t Schleife ' Eingabedatei

Wie geht's?

  • : loopist ein Label für das Looping; Ich werde es gleich verwenden.
  • s/\(\[[^][]*\)|\([^][]*\]\)/\1,\2/ersetzt ein Zeichen |, das zwischen [und ]mit einem Komma erscheint. Heruntergebrochen:

    s/ \( \[ [^][] * \) | \( [^][] * \] \) / \1,\2 / 
    • \(\)Begrenzt eine Search & Replace-Gruppe. Bei einem [... ]mit einem |zwischen ihnen, dies entspricht der [ bis zu (aber nicht einschließlich) die (letzten) | als eine Gruppe, und alles nach der |oben bis (einschließlich) die ]als eine zweite Gruppe.
    • \[entspricht einem wörtliche [.
    • [^][]passt zu einem beliebigen Zeichen außer [oder ]. Es bricht zusammen als
      [^] []
      dh eine Instanz von
      [^ zeichen_zu_nicht_match ]
    • *- null oder mehr Zeichen außer [oder ].
    • \)- Ende der Gruppe; oben diskutiert.
    • |ist ein Literal |(das wir ersetzen möchten).
    • Die zweite Hälfte des regulären Ausdrucks ist fast identisch mit der ersten Hälfte: Entsprechen Sie einer Gruppe, die aus null oder mehr Zeichen besteht, die nicht [oder sind ], gefolgt von einem ].
    • Ersetzen Sie dann alles durch die erste Gruppe, ein Komma und die zweite Gruppe. Da sich alles in der übereinstimmenden Zeichenfolge außer in der Gruppe in einer der Gruppen befindet, |ersetzt dies funktional die \durch die ,.
  • t loop- testen / übertragen Wenn der s Befehl eine Übereinstimmung gefunden und eine Ersetzung vorgenommen hat, kehren Sie zur Beschriftung zurück und versuchen Sie es erneut (da der s Befehl nur jeweils eine ersetzt |). Wenn keine Übereinstimmung gefunden wurde, beenden Sie das Befehlsskript und fahren Sie mit der nächsten Zeile fort.