Articles

Bash Sed Voorbeelden

Bash staat je toe om patroonvervanging uit te voeren met variabele uitbreiding zoals (${var/pattern/vervanging}). En dat doet sed ook, zoals dit (sed -e ‘s/pattern/replacement/’). Er is echter meer aan sed dan het vervangen van patronen in tekstbestanden. Hier zullen we sed herontdekken, aan de hand van voorbeelden, met equivalente commando’s en workflows om te helpen bij dagelijkse taken.

Opstelling voor sed voorbeelden

Hier volgt een snelle handleiding om op te zetten voor het voorbeeld, dat ik zal proberen niet te overkill te maken.

“words” is een tekstbestand dat de getallen 1 tot en met 100 bevat. Als je niet zeker bent van het commando om het te maken, zie Export functie voor xargs in Bash Export Commando. Je weet maar nooit of het in je volgende shell scripting interview voorkomt.

“bar” is een tekstbestand met een enkele regel -.

“old-php” is een tekstbestand met regels van oude PHP die in php7 of later zal breken. (Hint: ereg)

Noteer dat alle hierboven beschreven functies hieronder te vinden zijn in Eindnoot over functies voor setup.

Voorbeelden met equivalente commando’s

In een commandoregelomgeving zult u merken dat er meer dan één oplossing is voor een bepaalde taak. Meestal wil je echter de weg kiezen die de minste weerstand oplevert. Hier is een lijst van voorbeelden van sed commando’s met overeenkomstige equivalente commando’s, waarvan sommige hieronder in detail zullen worden behandeld.

1. Druk een willekeurige regel af (equivalent aan sort -R – | head -1)

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

2.De laatste regel in een bestand afdrukken (gelijk aan head -1 -)

sed -n ‘$p’ –

3. De eerste 10 regels in een bestand afdrukken (gelijk aan head -n 10 -)

sed ’10q’ –

4. De eerste regel in een bestand afdrukken (gelijk aan tail -1 -)

sed -n ‘1p’ –

5. Alle exemplaren van een teken verwijderen (gelijk aan tr -delete ‘0’ -, waarbij 0 het teken is dat we willen verwijderen)

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

6. Converteer csv-bestand naar tsv (equivalent met tr ‘,’ ‘\t’ -)

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

7.Voeg regel toe aan bestand (gelijk aan cat bar -)

sed ‘$a —‘ –

8. Zet regel voor aan bestand (gelijk aan cat – bar)

sed ‘1i —‘ –

9. Alle regels in het bestand afdrukken (gelijk aan cat -)

sed -n -e ‘p’ –

10. Print een regel die overeenkomt met een patroon (gelijk aan grep -e ‘^1’ -)

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

11. Verwijder regels die overeenkomen met een patroon (equivalent met grep -v -e ‘^1’ -)

sed -e ‘/^1/ d’ –

12. Het aantal regels in een bestand ophalen (gelijk aan wc -l -)

sed -n -e ‘$=’ –

13. Schrijf naar een bestand op de achtergrond (equivalent commando tee)

sed “w ${1}” –

Exemplaar met sed om het commando tee te implementeren

Hierboven staat een voorbeeld met het label Write to a file in the background. Dat klinkt een beetje als het tee commando. Nou, dat is het ook. Hier gaan we verder in op hoe we een functie kunnen implementeren om tee in bash te vervangen met behulp van sed.

Commando’s

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

Output

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

Hier ziet u twee lijsten van de gehele getallen van 1 tot 10. De eerste is van het seq commando. De tweede halen we uit de cat van het bestand geschreven in tee. Ik weet dat het belachelijk is, maar het werkt!

Exemplaar met sed om een willekeurige regel in een bestand uit te printen

Voorstel dat we een willekeurige regel in een bestand willen uitprinten met bash en een beetje sed. Kunnen we dat doen? Ja, dat kunnen we!

Emplementeer een functie die

  1. Haalt het aantal regels in een bestand, L
  2. Genereert een willekeurig getal tussen 1 en L, R
  3. Print R

De functie verwacht dat de invoer van buitenaf wordt gepijpt.

Commando’s

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

Voorbeeldgebruik (1)

seq 100 | _

Uitvoer (1)

35

Voorbeeldgebruik (2)

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

Zie het voorbeeld hieronder, waarin sed wordt gebruikt om HTML-tags te strippen. Merk op dat het over voorbeeld soms blanco retourneert voor lege regels. Als oefening kan het worden verbeterd.

Sed gebruiken om regels in een bestand af te drukken

Voorstel dat u een functie in bash wilt implementeren om een gegeven regel in een bestand af te drukken. Proberen om een enkele regel in een bestand af te drukken met behulp van een lus in bash, head, tail, of awk is te veel werk om regels in een bestand af te drukken. Maar goed dat we sed hebben. De resulterende functie met sed zou er als volgt uitzien.

Commando’s

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

Nu gaan we eens kijken wat er gebeurt als we print-line op woorden gebruiken.

Commando’s

words | print-line 50

Uitvoer

50

Oké. Ziet er goed uit, maar laten we eens iets proberen dat er iets minder triviaal uitziet.

Commando’s

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

Output

1
11
21
31
41
51
61
71
81
91

Okay. Dat lijkt er meer op! Je ziet hoe sed kan worden gebruikt in een bash script om elke regel in een bestand af te drukken.

Sed voorbeelden zonder equivalente commando’s

In een command-line omgeving is soms de weg naar een oplossing die de minste weerstand oplevert de sed manier; anders eindig je met meer werk te doen dan in eerste instantie nodig is. Hieronder volgen enkele commando’s.

Commandeer alle regels in een shellscript

sed -e ‘s/^/#/’ –
Verwijder eerste regel
sed -e ‘1d’ –
Verwijder laatste regel
sed -e ‘$ d’ –
Sed -e ‘$ d’ –
Sed -e ‘$ d’.
Voeg een regel in voor regels die overeenkomen met een patroon
sed ‘/0$/i —‘ –
Voeg een regel in na regels die overeenkomen met een patroon
sed ‘/0$/ —‘ –
Streep html-tags weg
sed -e ‘s/<*.//g’ –
Upgrade ereg in oude php code om te draaien in php7 of later
sed ‘s/ereg(\(*)./strpos(\2,\1)/g’
Controleer of sed eerder is dan een bepaalde versie
sed -e ‘v 4.5’ –

Voorbeeld sed versie aftakking in bash

Hierboven in de voorbeelden staat een regel om te controleren of sed eerder is dan een bepaalde versie die we kunnen gebruiken om versie aftakking in bash te implementeren, wat volgens mij eenvoudiger is dan te proberen een functie te implementeren om versienummers uit sed -versie uitvoer te vergelijken. De enige valkuil is dat als er een eerdere versie van sed is die het v commando niet ondersteunt, dat we dan in de problemen zitten.

Commando’s

test-sed-version-at-most() {
echo -n | sed “v ${1}” – 2>/dev/null
}
try-version ()
{
echo -n “Versie ${1}. Okay. Doe het “;
test-sed-version-at-most ${1} && {
echo -n “old”;
true
} || {
echo -n “new”
};
echo ” way.”
}
main ()
{
local v;
for v in 4.{4,5};
do
try-version ${v};
done
}
main

Output

Versie 4.4. Okay. Doe het op de oude manier.
Versie 4.5. Okay. Doe het op de nieuwe manier.

Merk op dat de versie van sed die op mijn machine draait op het moment dat ik deze tekens typ, 4.4 is, wat de bovenstaande uitvoer zou verklaren. Op hetzelfde moment was de laatste versie van gnu sed 4.7, ongeveer 3 jaar ouder dan de versie die ik heb. Mijn sed is oud! In feite, in sed 4.0.6, is een parameter toegevoegd aan het versie commando zodat deze strategie werkt voor elke zei op zijn minst v4.0.6, wat coulant is gezien het feit dat die versie werd uitgebracht in begin 2003. Je bent goed.

Ik heb wat extra gegraven, eigenlijk NIEUWS uit de laatste broncode gelezen. Versie 4.6 heeft een nieuwe functie, -debug, die het script dumpt en de uitvoerregels annoteert. Dit zou je in staat stellen om sed scripts gegenereerd door functies in bash te vertalen naar canonieke vorm. Cool! Vergeet alleen niet dat je sed versie vertakking nodig hebt in bash. Dat is waar dit sed voorbeeld in het spel komt.

Exemplaar bash functie met sed om HTML tags te strippen

In de voorbeelden hierboven staat een regel om HTML tags te strippen. Laten we dat in een bash functie gooien en gebruiken om alle HTML tags uit het laatste artikel dat ik schreef te strippen.

Commando’s

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

Ik kan niet zeggen dat het perfect is, maar het is in ieder geval leesbaar in de terminal.

Voorbeelden met workflows: Voorbeeld workflow: veilig alles vervangen met behulp van find, grep en sed

Het is veilig om te zeggen dat veranderingen gemaakt met sed met de -i optie onomkeerbaar zijn. Dat wil zeggen, tenzij je helemaal zeker weet welke tekst vervangen moet worden, zul je waarschijnlijk eindigen met een karakter minder dan bedoeld. Daarom zullen we in dit voorbeeld sed gebruiken in een workflow om veilig tekst te vervangen in alle bestanden die je hebt geselecteerd.

Workflow

  1. find
  2. grep
  3. sed
find

Hier selecteer je de bestanden die je wilt vervangen. Ik stel voor om een commando van deze strekking te gebruiken:

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

U kunt bijvoorbeeld als volgt de bestanden beperken om PHP-bestanden te vervangen met uitsluiting van de git repository directories.

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

Lees meer over het xargs commando in bash.

grep

Volgende gaan we proberen te matchen met some_pattern in de als volgt geselecteerde bestanden. Merk op dat omdat we de -o optie voor grep gebruiken, de uitvoer alleen de gematchte string zal laten zien als die er is.

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

Het bovenstaande commando zou een lijst moeten opleveren met strings die overeenkomen met some_pattern.

sed

Uit eindelijk willen we alle strings die overeenkomen met some_pattern vervangen. Om dat te doen moeten we grep als volgt omzetten in sed.

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

Het grep-commando wordt sed -i en de -o optie wordt verwijderd. En daar heb je het.

Nu kun je van tevoren controleren welke strings vervangen gaan worden in sed in plaats van je geluk te beproeven.

Eindnoten over opties gebruikt in voorbeelden

Hier volgt een lijst met opties die gebruikt worden in de sed voorbeelden die kort besproken zijn.

Option Description
-i Plaats bewerken. Als de invoer een bestand is (niet gepijpt) zal het resultaat van de expressies de inhoud van het bestand overschrijven.

Sed accepteert een

eg) sed -n …

-e -e staat voor expressie. De parameter is een expressie in de sed taal.

Sed accepteert vele

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

-n Verbergt regel die niet wordt beïnvloed door de expressie. Dat wil zeggen dat als de expressie een afdrukstatement is in de sed taal, dan zullen regels die niet in het afdrukstatement zijn opgenomen niet in de uitvoer worden opgenomen.

eg) sed -n …

Voor meer over de beschikbare sed opties, zie sed -help

Aantekeningen over het gebruik van equivalente commando’s in de voorbeelden

De volgende command-line hulpprogramma’s zijn opgenomen in de sed voorbeelden met equivalente commando’s.

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

Endnote over de trailing – in voorbeeld equivalente commando’s

In het geval dat je je afvraagt wat er aan de hand is met het – karakter in het voorbeeld, dan is deze noot voor jou. Ik heb een – karakter toegevoegd na de meeste commando’s in de voorbeelden om aan te geven dat we verwachten dat de invoer via een pipe wordt ontvangen. Dat wil zeggen,

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

Als echter het commando links van de pipe aanwezig is, kunnen we de hint als volgt weglaten.

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

Dit is wat er aan de hand was met het – teken na commando’s in de voorbeelden.

Eindnoten bij functies voor setup

Voor het geval u op zoek bent, hier zijn functies voor de setup voor de bovenstaande voorbeelden. De uitvoer verkregen met declare -f. Lees meer over het commando declare in bash voor meer gebruiksmogelijkheden.

Commando’s

words ()
{
seq 100
}
bar ()
{br>echo —
}
old-php ()
{
echo ‘ereg($UA, “Bottybot”)’
}

Bottom line

Ik heb genoten van het schrijven van Bash sed voorbeelden en heb zelfs een paar extra trucs opgepikt onderweg. Sed is een krachtig hulpprogramma voor de commandoregel en een expressieve taal voor het manipuleren van tekstbestanden. Als je het leuk vond om over sed te leren, maak je dan geen zorgen er is nog veel meer om aan te raken. Sed op.

Laat een antwoord achter

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *