Wie kann ich feststellen, wie viele Zeilen mit einem SED-Befehl in Bash Script gelöscht wurden?

0

Wie schreibe ich ein Shell-Skript, das zählt und ausgibt, wie viele Änderungen bei der Ausführung eines SED-Befehls vorgenommen wurden?

Beispiel: Verwenden Sie den Befehl SED, um jede Zeile zu löschen, wenn sie einem bestimmten Zeichen entspricht.

sed '/@gmail.com/d' F1.txt > RESULT.txt

F1.txt-Datei enthält:

abc123@gmail.com
zyz123@gmail.com
fgh456@yahoo.com
ght4789@msn.com

Die Ausgabe dieser Datei wäre:

fgh456@yahoo.com
ght4789@msn.com

Daher wurden zwei Zeilen abgeglichen und die beiden Zeilen gelöscht.

Nun, wie kann man dies in einem Shell-Skript mit einem Echo wiedergeben und vorschlagen, wie viele Zeilen durch diesen SED-Befehl geändert / gelöscht wurden?

Es sollte klingen und Print / Echo, 2 Zeilen wurden gelöscht. Können Sie bitte helfen, wie man dieses Shell-Skript erstellt?

#!/bin/bash
sed '/@gmail.com/d' F1.txt > RESULT.txt
Joney Walker
quelle
Sie können wc -lfür beide Dateien verwenden und die Differenz berechnen.
AFH
Können Sie mir bitte helfen, ein Shell-Skript zu schreiben, das die Anzahl der mit diesem SED-Befehl vorgenommenen Änderungen wiedergibt?
Joney Walker
Verwenden Sie $(wc -l <FileName), um jede Zeilenzahl und $((ArithmeticExpression))die Differenz zurückzugeben.
AFH
Ich habe verstanden, wie man wc -l benutzt, aber ich kann $ ((ArithmeticExpression)) nicht implementieren. Können Sie mir bitte dabei helfen, indem Sie die gesamte Codezeile schreiben? PLZ
Joney Walker
Hast du $(( ... ))im Handbuch nachgeschlagen? Was hast du nicht verstanden
AFH

Antworten:

1

Wenn Sie mit zwei Befehlen zufrieden sind, können Sie Folgendes tun:

NUM_DELETIONS=$( grep "@gmail.com" F1.txt | wc -l )
sed '/@gmail.com/d' F1.txt > RESULT.txt

echo "${NUM_DELETIONS} lines were deleted from F1.txt"

Wenn Sie es als schnelles und unsauberes bashSkript schreiben möchten , können Sie es auch so machen:

#!/bin/bash

usage(){
    echo "$0 <source_file> <output_file> <removal_text>"
}

SOURCE_FILE="${1}"
OUTPUT_FILE="${2}"
REMOVAL_TEXT="${3}"

[[ ! -r "${SOURCE_FILE}" ]] && usage && exit 1
[[ -z "${REMOVAL_TEXT}" ]] && usage && exit 1

NUM_DELETIONS=$( grep "${REMOVAL_TEXT}" "${SOURCE_FILE}" | wc -l )
sed "/${REMOVAL_TEXT}/d" "${SOURCE_FILE}" > "${OUTPUT_FILE}"

echo "${NUM_DELETIONS} lines were deleted from "${SOURCE_FILE}""
Chuck Wolber
quelle
1
Namenskonvention .
Kamil Maciorowski
Vielen Dank. Dies funktioniert. Ich habe bereits herausgefunden, dass ich dies im Falle einer Ersetzung ändern kann. Aber können Sie bitte erklären, was diese beiden Zeilen 11 und 12 bewirken: [[! -r "$ {SOURCE_FILE}"]] && usage && exit 1 ------- [[-z "$ {REMOVAL_TEXT}"]] && usage && exit 1
Joney Walker
Diese Zeilen validieren Ihre Befehlszeilenargumente. In der Regel empfiehlt es sich, die Argumente für das Programm zu validieren, bevor Sie sie verwenden. Wenn die Argumente falsch sind, wird die Verwendungserklärung gedruckt, um den Benutzer bei der Behebung des Problems zu unterstützen.
Chuck Wolber
Ok, ich verstehe ... Warum hast du [! -r] bei Quelldatei und [-z] bei Entfernungstext. Können Sie bitte den Unterschied zwischen ihnen erklären?
Joney Walker
1
Das sind bash bedingte Ausdrücke. Bash hat alle möglichen bedingten Ausdrücke, um alle möglichen nützlichen Dinge zu tun. Im obigen Fall -zist wahr, wenn die Variable leer ist. Der -rAusdruck ist wahr, wenn die Datei vorhanden und lesbar ist. Wenn Sie die gesamte Liste der bedingten Ausdrücke anzeigen möchten, führen Sie einfach den Befehl aus man bashund suchen Sie nach CONDITIONAL EXPRESSIONS. PS Schonende Erinnerung - Sie sollten in Betracht ziehen, eine der Antworten auf Ihre Frage als richtig zu markieren. Es belohnt die Person, die Ihnen antwortet.
Chuck Wolber
2

Hier ist eine Möglichkeit, dies zu tun:

echo $(( $(wc -l < F1.txt) - $(wc -l < RESULT.txt) ))

Dies wc -list eine Anzahl von Zeilen, <die von der "Standardeingabe" gelesen werden.

Jedes wcwird $()in die Ausgabe eingewickelt, in der es nur ersetzt.

Das $(( ... ))ist Shell-Arithmetik (wie jemand in einem Kommentar sagte). Beachten Sie das Minuszeichen in der Mitte.

Variablen könnten es klarer machen; Hier ist eine andere Version der gleichen Sache:

all=$(wc -l < F1.txt)
sed=$(wc -l < RESULT.txt)
echo $(($all - $sed))
Tommy Jollyboat
quelle