2017-08-08 4 views
0

Ich würde gerne eine Reihe von sed-Befehle in Zeilen einer Datei roster.txt nur mit einem Schlüsselwort beginnen. Zum Beispiel:Sed in einer Awk-Anweisung

Employee : Kiara 20 [email protected] 
Employee : Connor 25 [email protected] 
Employee : Dylan 30 [email protected] 

Becomes:

Employee : Kiara_20_hoursat8dot25 
Employee : Connor_25_hoursat8dot00 
Employee : Dylan_30_hoursat9dot00 

ich die sed-Befehle kennen die Änderungen vornehmen wollte ich nur einen Weg, um sie auf Strecken mit „Mitarbeiter“ ab peform. Vielleicht

awk '$1 == "Employee" {sed -i -e 's/\./dot/g' roster.txt}' roster.txt 
+0

Sie mit sed/awk gesperrt sind oder nehmen Sie jede Shell-Skript Linie als Lösung? – Fabien

+0

Sie brauchen nie sed, wenn Sie awk verwenden und Sie müssen sed niemals innerhalb von awk aufrufen! –

Antwort

2
$ cat roster.txt 
foo : [email protected] 
Employee : Kiara 20 [email protected] 
Employee : Connor 25 [email protected] 
Employee : Dylan 30 [email protected] 

$ awk 'BEGIN{FS=OFS=" : "} $1=="Employee"{gsub(/ /,"_",$2); gsub(/@/,"at",$2); gsub(/\./,"dot",$2)} 1' roster.txt 
foo : [email protected] 
Employee : Kiara_20_hoursat8dot25 
Employee : Connor_25_hoursat8dot00 
Employee : Dylan_30_hoursat9dot00 

awk unterstützt Ersetzungsbefehle auch - sub, um zuerst occurre zu ersetzen nce und gsub, um alle Vorkommen zu ersetzen. nur bestimmte Feld ermöglicht auch

mit _ zum zweiten Feld als
  • Ähnlich andere Substitutionen nur
    • BEGIN{FS=OFS=" : "} Verwendung : als Eingabe/Ausgabe-Feldseparator
    • gsub(/ /,"_",$2) ersetzen alle Räume verändern
    • erforderlich
    • 1 am Ende der Befehl ist idiomatische Art, die Linie zu drucken, schließt alle vorgenommenen Änderungen ein
    • Siehe auch awk save modifications in place
  • +0

    wird dies in die ursprüngliche Datei schreiben? – cbrad97

    +0

    @ cbrad97 siehe https://stackoverflow.com/questions/16529716/awk-save-modifications-in-place – Sundeep

    +0

    also, wenn ich nicht GAWK 4.1 oder später habe, muss ich eine temporäre Datei erstellen, um zu schreiben? Ich brauche den ursprünglichen Namen der Datei, um intakt zu sein – cbrad97

    0

    Sie müssen wirklich nicht beide Werkzeuge verwenden, wird entweder alles tun, was Sie brauchen.

    sed Lösung:

    sed -i -e 's/^Employee : \([^ ]*\) \([0-9]*\) [email protected]\([0-9]\)\.\([0-9]*\)/Employee : \1_\2_hoursat\3dot\4/' roster.txt 
    

    bearbeiten nach Kommentar:

    Wenn Sie einen sehr generischen Ersatz nur mit sed, die auf Ihrem Beispiel funktioniert:

    sed -i -e 's/\([^:]\) \([^:]\)/\1_\2/g' -e 's/@/at/g' -e 's/\./dot/g' roster.txt 
    
    +0

    Was, wenn ich die Felder nicht kenne, die dem Doppelpunkt folgen? Ich weiß nur, dass ich eine Reihe von sed-Substitutionen für jeden Text nach dem Doppelpunkt ausführen muss. – cbrad97

    +0

    machen das Muster allgemeiner. Sie wollen das und halten Sie das Muster so restriktiv wie möglich, während immer noch alle Ihren Fall erfassen das letzte, was Sie wollen, ist für eine Ersetzung auftreten, dass Sie nicht vorhatten. Ich werde eine weitere Option hinzufügen, die an der Stichprobe arbeitet, aber möglicherweise riskanter ist. – Rob

    2

    Ich würde schreiben:

    sed '/^Employee :/ {s/@/at/; s/\./dot/; s/ /_/3g}' <<END 
    Employee : Kiara 20 [email protected] 
    Employee : Connor 25 [email protected] 
    Employee : Dylan 30 [email protected] 
    Foo : bar [email protected] 
    END 
    
    Employee : Kiara_20_hoursat8dot25 
    Employee : Connor_25_hoursat8dot00 
    Employee : Dylan_30_hoursat9dot00 
    Foo : bar [email protected] 
    

    Benötigt GNU für die 3g Modifikator des Befehls s sed

    +0

    gut, obwohl ich'! b' verwendet hätte, siehe https://www.gnu.org/software/sed/manual/sed. html # Programming-Commands – Sundeep

    +0

    Bedeutet next record meine nächste Datei oder nächste Zeile in der aktuellen Datei? Wenn ich den Befehl ausführe, wird! N durch einen anderen Dateinamen ersetzt? – cbrad97

    +0

    Ich denke, das ist Bash [History-Erweiterung] (https://www.gnu.org/software/bash/manual/bashref.html#History-Interaction), wobei '! N' der vorherige Befehl ist, der mit" n "beginnt ". Versuchen Sie, die Hist-Expansion mit 'set + H' auszuschalten (schalten Sie sie danach mit' set -H' ein) –