sed

sed

Ich habe eine Datei wie:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,

Ich muss die Zeilen mit Zeitstempel beibehalten, d. h. 171023 03014426 1234 XXXX XXXXXXXXund den Abstand error code: 123zu den anderen Zeilen beibehalten, d. h. vom Zeilenanfang bis zum Komma, und die Änderungen in dieselbe Datei schreiben.

Ausgabe:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Wie kann ich das machen?

Antwort1

So wie ich Ihre Frage verstehe, möchten Sie dies

171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,

um dies zu werden:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Hierfür gibt es viele Möglichkeiten. Wählen Sie also die Methode, die Ihnen gefällt/die Sie bevorzugen.

sed

$ sed 's/\(error code:[[:blank:]][[:digit:]]*\),.*/\1/' input.txt                                     
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Wenn Sie Änderungen an der Originaldatei vornehmen möchten input.txt, verwenden Sie sed -istatt nursed

awk

$ awk -F ',' '/^error code/{$0=$1};1' input.txt                                                       
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Bei diesem Ansatz wird das Komma als Spaltentrennzeichen (in der Awk-Sprache „Feld“) behandelt. Hier suchen wir also grundsätzlich nach der Zeile, die mit error codeText beginnt, und ersetzen die ursprüngliche Zeile nur durch die Spalte $1, was in Ihrem Fall alles vor dem Komma ist, d. h error code: 123.

awkkeine Textbearbeitung möglich (die meisten Versionen), sed -iaber Sie können die Ausgabe immer in eine neue Datei vornehmen und die alte Datei durch eine neue ersetzen, wie:

awk -F ',' '/^error code/{$0=$1};1' input.txt > new_data.txt && mv new_data.txt input.txt 

reines Bash

#!/usr/bin/env bash

# make temp file for writing stuff
temp=$(mktemp)

# read input file, make necessary changes, write to temp file
while IFS= read -r line;
do
    case $line in
        "error code:"*) printf "%s\n" "${line%%,*}" >> "$temp";;
        *) printf "%s\n" "$line" >> "$temp";;
    esac
done < "$1"
mv  "$temp" "$1"

Testlauf:

$ # before 
$ cat input.txt                                                                                       
171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
$ # after
$ ./edit_error_codes.sh input.txt                                                                     
$ cat input.txt
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Antwort2

Wenn die Zeilen, die Sie nicht ändern möchten, keine Kommas enthalten und Sie immer nur das erste Komma und alles danach löschen möchten, können Sie einen sehr einfachen Ausdruck verwenden

$ sed 's/,.*//' file
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123
  • s/old/new/ersetzen oldmitnew
  • .*eine beliebige Anzahl beliebiger Zeichen

Um die Datei direkt zu bearbeiten, verwenden Sie die sedIn-Place-Option von , die lautet -i. Wenn nach ein Suffix für die Sicherungsdatei hinzugefügt wird -i, wird automatisch eine Sicherungskopie der Originaldatei mit dieser Erweiterung in dasselbe Verzeichnis geschrieben, zum Beispiel

sed -i 's/,.*//' file

überschreibt filemit dem geänderten Stream, aber

sed -i.orig 's/,.*//' file

schreibt den geänderten Stream fileund erstellt eine neue Datei file.origmit dem ursprünglichen Inhalt.

Antwort3

Sie können einen einfachen cutBefehl verwenden, um zu tun, was Sie möchten.

cut -d"," -f1 input.txt

Schreiben Sie es in dieselbe Datei zurück.

cut -d"," -f1 input.txt | tee input.txt

verwandte Informationen