Articles

Bash-Sed-Beispiele

Mit der Bash können Sie Musterersetzungen durch Variablenexpansion wie (${var/pattern/replacement}) durchführen. Das tut auch sed wie hier (sed -e ’s/pattern/replacement/‘). Doch sed kann mehr als nur Muster in Textdateien zu ersetzen. Hier werden wir sed anhand von Beispielen mit entsprechenden Befehlen und Arbeitsabläufen wiederentdecken, die bei den täglichen Aufgaben helfen.

Aufbau für sed-Beispiele

Hier ist eine kurze Anleitung, um sich für das Beispiel einzurichten, die ich versuchen werde, nicht zu übertrieben zu machen.

„words“ ist eine Textdatei, die die Zahlen 1 bis 100 enthält. Wenn Sie sich nicht sicher sind, mit welchem Befehl Sie sie erstellen können, lesen Sie bitte die Exportfunktion für xargs in Bash Export Command. Man kann nie wissen, ob es in Ihrem nächsten Shell-Skripting-Interview vorkommt.

„bar“ ist eine Textdatei, die eine einzelne Zeile enthält -.

„old-php“ ist eine Textdatei, die Zeilen von altem PHP enthält, die in php7 oder später abbrechen. (Tipp: ereg)

Beachten Sie, dass alle oben beschriebenen Funktionen weiter unten in der Endnote zu Funktionen für das Setup zu finden sind.

Beispiele mit äquivalenten Befehlen

In einer Kommandozeilenumgebung werden Sie feststellen, dass es mehr als eine Lösung für eine bestimmte Aufgabe gibt. In den meisten Fällen wollen Sie jedoch den Weg gehen, der den geringsten Widerstand bietet. Hier ist eine Liste von Beispielen für sed-Befehle mit entsprechenden äquivalenten Befehlen, von denen einige weiter unten im Detail behandelt werden.

1. Eine zufällige Zeile ausgeben (äquivalent zu sort -R – | head -1)

sed -n „$(( RANDOM % 100 ))p“ –

2.Die letzte Zeile in der Datei ausgeben (entspricht head -1 -)

sed -n ‚$p‘ –

3. Die ersten 10 Zeilen in einer Datei ausgeben (entspricht head -n 10 -)

sed ’10q‘ –

4. Die erste Zeile in einer Datei ausgeben (entspricht tail -1 -)

sed -n ‚1p‘ –

5. Alle Instanzen eines Zeichens löschen (entspricht tr -delete ‚0‘ -, wobei 0 das Zeichen ist, das wir löschen wollen)

sed -e ’s/0//g‘ –

6. csv-Datei in tsv umwandeln (entspricht tr ‚,‘ ‚\t‘ -)

sed -e ’s/,/\t/g‘ –

7.Zeile an Datei anhängen (entspricht cat bar -)

sed ‚$a —‚ –

8. Zeile an Datei voranstellen (entspricht cat – bar)

sed ‚1i —‚ –

9. Alle Zeilen in der Datei ausgeben (äquivalent zu cat -)

sed -n -e ‚p‘ –

10. Eine auf ein Muster passende Zeile ausgeben (entspricht grep -e ‚^1‘ -)

sed -n -e ‚/^1/ p‘ –

11. Zeilen löschen, die einem Muster entsprechen (entspricht grep -v -e ‚^1‘ -)

sed -e ‚/^1/ d‘ –

12. Die Anzahl der Zeilen in einer Datei ermitteln (entspricht wc -l -)

sed -n -e ‚$=‘ –

13. In eine Datei im Hintergrund schreiben (äquivalenter Befehl tee)

sed „w ${1}“ –

Beispiel für die Verwendung von sed zur Implementierung des tee-Befehls

Rechts oben steht ein Beispiel mit der Bezeichnung In eine Datei im Hintergrund schreiben. Klingt irgendwie wie der tee-Befehl. Nun, das ist er auch. Hier werden wir erläutern, wie man eine Funktion implementiert, die tee in der Bash mit sed ersetzt.

Befehle

tee ()
{
test ${#} -eq 1 || return;
sed „w ${1}“ –
}
main ()
{
seq 10 | tee ten;
cat ten
}
main

Ausgabe

1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10

Hier sehen Sie zwei Auflistungen der Ganzzahlen von 1 bis 10. Die erste stammt aus dem Befehl seq. Die zweite erhalten wir aus dem cat der in tee geschriebenen Datei. Ich weiß, es ist lächerlich, aber es funktioniert!

Beispiel mit sed zum Ausdrucken einer zufälligen Zeile in einer Datei

Angenommen, wir wollen eine zufällige Zeile in einer Datei mit der Bash und ein wenig sed ausdrucken. Können wir das tun? Ja, wir können! So geht’s.

Implementieren Sie eine Funktion, die

  1. Die Anzahl der Zeilen in einer Datei, L
  2. Erzeugt eine Zufallszahl zwischen 1 und L, R
  3. Druckt R

Die Funktion erwartet, dass die Eingabe von außen zugeführt wird.

Befehle

some-line ()
{
function lc ()
{
sed -n -e ‚$=‘ –
};
function print-line ()
{
sed -n -e „${1}p“ –
};
temp=$( mktemp );
cat – > ${temp};
cat ${temp} | print-line $(( RANDOM % $( cat ${temp} | lc ) + 1 ));
rm ${temp}
}

Beispielanwendung (1)

seq 100 | _

Ausgabe (1)

35

Beispielanwendung (2)

curl https://linuxhint.com/bash_cut_command/ –silent | strip-tags | some-line

Siehe das Beispiel unten, das sed verwendet, um HTML-Tags zu entfernen. Beachten Sie, dass das over-Beispiel manchmal Leerzeichen für leere Zeilen zurückgibt. Als Übung kann es verbessert werden.

Using sed to print lines in a file

Angenommen, Sie wollen in der Bash eine Funktion implementieren, die eine bestimmte Zeile in einer Datei ausgibt. Der Versuch, eine einzelne Zeile in einer Datei mit einer Schleife in bash, head, tail oder awk auszudrucken, ist zu viel Arbeit für das Ausdrucken von Zeilen in einer Datei. Gut, dass wir sed haben. Die resultierende Funktion mit sed würde wie folgt aussehen.

Befehle

print-line ()
{
sed -n „${1}p“ –
}

Nun wollen wir mal sehen, was passiert, wenn wir print-line auf Wörter anwenden.

Befehle

words | print-line 50

Ausgabe

50

Ok. Sieht gut aus, aber lassen Sie uns etwas versuchen, das etwas weniger trivial aussieht.

Befehle

declare -xf words
declare -xf print-line
seq 1 10 $( words | wc -l ) | xargs -i bash -c „words | print-line {}“

Ausgabe

1
11
21
31
41
51
61
71
81
91

Ok. Das ist schon besser! Sie sehen, wie sed in einem Bash-Skript verwendet werden kann, um eine beliebige Zeile in einer Datei auszudrucken.

Sed-Beispiele ohne äquivalente Befehle

In einer Kommandozeilenumgebung ist manchmal der Weg zu einer Lösung, die den geringsten Widerstand leistet, der sed-Weg; andernfalls macht man sich am Ende mehr Arbeit als überhaupt nötig. Im Folgenden werden einige Befehle vorgestellt.

Alle Zeilen in einem Shell-Skript löschen

sed -e ’s/^/#/‘ –
Die erste Zeile löschen
sed -e ‚1d‘ –
Die letzte Zeile löschen
sed -e ‚$ d‘ -.
Zeile vor Zeilen einfügen, die auf ein Muster passen
sed ‚/0$/i —‚ –
Zeile nach Zeilen einfügen, die auf ein Muster passen
sed ‚/0$/ —‚ –
HTML-Tags abschneiden
sed -e ’s/<*.//g‘ –
Ereg in altem php-Code so anpassen, dass er in php7 oder neuer läuft
sed ’s/ereg(\(*\).\(*\)./strpos(\2,\1)/g‘
Prüfen, ob sed älter als eine bestimmte Version ist
sed -e ‚v 4.5‘ –

Beispiel sed Versionsverzweigung in Bash

Oben in den Beispielen gibt es eine Zeile, um zu prüfen, ob sed früher als eine bestimmte Version ist, die wir verwenden können, um Versionsverzweigung in Bash zu implementieren, was meiner Meinung nach einfacher ist, als zu versuchen, eine Funktion zu implementieren, um Versionsnummern aus der sed -version Ausgabe zu vergleichen. Der einzige Fallstrick ist, dass, wenn es eine frühere Version von sed gibt, die den v-Befehl nicht unterstützt, dann sind wir in Schwierigkeiten.

Befehle

test-sed-version-at-most() {
echo -n | sed „v ${1}“ – 2>/dev/null
}
try-version ()
{
echo -n „Version ${1}. Okay. Machen Sie die „;
test-sed-version-at-most ${1} && {
echo -n „alt“;
true
} || {
echo -n „neu“
};
echo “ way.“
}
main ()
{
local v;
for v in 4.{4,5};
do
try-version ${v};
done
}
main

Output

Version 4.4. Okay. Mach es auf die alte Art.
Version 4.5. Okay. Machen Sie es auf die neue Art.

Beachten Sie, dass die Version von sed, die zum Zeitpunkt des Tippens dieser Zeichen auf meinem Rechner läuft, 4.4 ist, was die obige Ausgabe erklären würde. Außerdem war zur gleichen Zeit die letzte Version von gnu sed 4.7, etwa 3 Jahre älter als die, die ich habe. Mein sed ist alt! Tatsächlich wurde in sed 4.0.6 ein Parameter zum Versionsbefehl hinzugefügt, so dass diese Strategie für jede besagte Version ab v4.0.6 funktioniert, was nachsichtig ist, wenn man bedenkt, dass diese Version Anfang 2003 veröffentlicht wurde. Sie sind gut.

Ich habe ein wenig nachgeforscht, eigentlich NEWS aus dem aktuellen Quellcode gelesen. Version 4.6 hat eine neue Funktion, -debug, die das Skript ausgibt und die Ausgabezeilen mit Anmerkungen versieht. Damit kann man sed-Skripte, die von Funktionen in der Bash erzeugt werden, in eine kanonische Form übersetzen. Cool! Vergessen Sie nur nicht, dass Sie sed-Versionsverzweigungen in der Bash benötigen. Hier kommt dieses sed-Beispiel ins Spiel.

Beispiel einer Bash-Funktion, die sed zum Strippen von HTML-Tags verwendet

In den obigen Beispielen gibt es eine Zeile zum Strippen von HTML-Tags. Werfen wir das in eine Bash-Funktion und verwenden es, um alle HTML-Tags aus dem letzten Artikel zu entfernen, den ich geschrieben habe.

Befehle

strip-tags ()
{
sed -e ’s/<*.//g‘ –
}
curl https://linuxhint.com/bash_cut_command/ –silent | strip-tags

Ich kann nicht sagen, dass es perfekt ist, aber zumindest ist es im Terminal lesbar.

Beispiele mit Workflows: Beispiel-Workflow: Alles sicher ersetzen mit find, grep und sed

Es ist sicher, dass Änderungen, die mit sed mit der Option -i gemacht werden, irreversibel sind. Das heißt, wenn Sie sich nicht völlig sicher sind, welcher Text ersetzt werden soll, ist es wahrscheinlich, dass Sie am Ende ein Zeichen weniger haben als beabsichtigt. Deshalb werden wir in diesem Beispiel sed in einem Arbeitsablauf verwenden, um Text in allen ausgewählten Dateien sicher zu ersetzen.

Arbeitsablauf

  1. find
  2. grep
  3. sed
find

Hier werden Sie die Dateien auswählen, die ersetzt werden sollen. Ich schlage vor, einen Befehl nach diesem Muster zu verwenden:

find -type f -name | grep -v -e | xargs -i …

Zum Beispiel können Sie die zu ersetzenden Dateien wie folgt einschränken, wobei PHP-Dateien aus den Verzeichnissen des Git-Repositorys ausgeschlossen werden.

find -type f -name \*.php | grep -v -e ‚.git‘ | xargs -i …

Lesen Sie mehr über den Befehl xargs in der Bash.

grep

Als Nächstes werden wir versuchen, some_pattern in den wie folgt ausgewählten Dateien zu finden. Beachten Sie, dass, da wir die Option -o für grep verwenden, die Ausgabe nur die übereinstimmende Zeichenkette anzeigt, falls vorhanden.

find -type f -name \*.php | grep -v -e ‚.git‘ |
xargs -i grep -e some_pattern -o

Der obige Befehl sollte eine Liste von Zeichenketten zurückgeben, die auf some_pattern passen.

sed

Schließlich wollen wir alle Zeichenketten ersetzen, die auf some_pattern passen. Dazu müssen wir grep wie folgt in sed umwandeln.

find -type f -name \*.php | grep -v -e ‚.git‘ |
xargs -i sed -i -e s/some_pattern/replacement/g

Der Befehl grep wird zu sed -i und die Option -o wird entfernt. Und schon haben Sie es.

Nun können Sie vorher prüfen, welche Zeichenketten in sed ersetzt werden sollen, anstatt Ihr Glück zu testen.

Endnoten zu den in den Beispielen verwendeten Optionen

Hier ist eine Liste der Optionen, die in den kurz besprochenen sed-Beispielen verwendet werden.

Option Beschreibung
-i Bearbeiten an Ort und Stelle. Wenn die Eingabe eine Datei ist (nicht über eine Pipeline), überschreibt das Ergebnis von Ausdrücken den Inhalt der Datei.

Sed akzeptiert einen

eg) sed -n …

-e -e steht für Ausdruck. Sein Parameter ist ein Ausdruck in der Sprache sed.

Sed akzeptiert viele

eg) sed -e ‚expr1′ -e ‚expr2‘ …

-n Blendet eine Zeile aus, die nicht von dem Ausdruck betroffen ist. Das heißt, wenn der Ausdruck eine Druckanweisung in der Sprache sed ist, dann werden die Zeilen, die nicht von der Druckanweisung betroffen sind, nicht in die Ausgabe aufgenommen.

eg) sed -n …

Weitere Informationen zu den verfügbaren sed-Optionen finden Sie unter sed -help

Hinweise zu äquivalenten Befehlen, die in den Beispielen verwendet werden

Die folgenden Kommandozeilen-Dienstprogramme sind in den sed-Beispielen mit äquivalenten Befehlen enthalten.

  • sort
  • head
  • tail
  • grep
  • cat
  • Tr
  • tee

Endnotiz zum abschließenden – in den äquivalenten Befehlen der Beispiele

Wenn Sie sich fragen, was es mit dem –Zeichen in den Beispielen auf sich hat, ist diese Notiz für Sie. Ich habe ein – Zeichen nach den meisten Befehlen in den Beispielen hinzugefügt, um anzudeuten, dass wir erwarten, dass die Eingabe durch eine Pipe empfangen wird. Das heißt,

cat some-file | sort -R – | head -1

Wenn jedoch der Befehl links von der Pipe steht, können wir den Hinweis wie folgt weglassen.

cat some-file | sort -R | head -1

Das war es dann mit dem – Zeichen nach den Befehlen in den Beispielen.

Endnoten zu den Funktionen für das Setup

Für den Fall, dass Sie auf der Suche sind, hier die Funktionen zum Setup für die obigen Beispiele. Die Ausgabe erhalten Sie mit declare -f. Lesen Sie mehr über den declare-Befehl in der Bash für weitere Verwendungen.

Befehle

words ()
{
seq 100
}
bar ()
{
echo —
}
old-php ()
{
echo ‚ereg($UA, „Bottybot“)‘
}

Fazit

Es hat mir Spaß gemacht, die sed-Beispiele für die Bash zu schreiben, und ich habe dabei sogar ein paar zusätzliche Tricks aufgeschnappt. Sed ist ein mächtiges Kommandozeilenprogramm und eine ausdrucksstarke Sprache zur Manipulation von Textdateien. Wenn es Ihnen gefallen hat, sed kennenzulernen, keine Sorge, es gibt noch viel mehr, das Sie anfassen können. Sed an.

Eine Antwort schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.