Script: Tekst vervangen in bestanden

Alles over programmeren in Linux
Gebruikersavatar
Mogenblue
Held
Held
Berichten: 351
Lid geworden op: Wo 18 Okt 2017, 08:27
Locatie: Amsterdam

Script: Tekst vervangen in bestanden

Berichtdoor Mogenblue » Wo 11 Jan 2023, 20:42

In bash kun je ook teksten laten vervangen in bestanden. In deze post wordt een aantal scripts gegeven om teksten te vervangen
- in 1 bestand
- in een reeks bestanden in 1 map
- in een reeks bestanden in een reeks mappen.

Er wordt gebruik gemaakt van het sed commando. In een terminal kun je de man page opvragen met man sed om alle ins en outs van sed te zien.

Het eerste script vervangt de tekst in 1 bestand.

Het bestand heet replace-text-in-file.sh en dit staat er in:

Code: Selecteer alles

#!/bin/bash

# replace text in files
#sed -i 's/source text/target text/g' "$InputFile"

# voor uitleg in terminal: man sed

# gebruik \n in sed om een nieuwe regel in te voegen

# speciale tekens escapen met \

# opdracht over meer regels uitspreiden met \

#------------------------------------------------------------------------------------------------------------------------------------------


InputFile='/home/popeye/Documenten/texten/text map 1/text bestand.txt'


#------------------------------------------------------------------------------------------------------------------------------------------

# functie om tekst te vervangen in 1 bestand
ReplaceText () {

echo $InputFile
sed -i 's/source text/target text/g' "$InputFile"

}

#------------------------------------------------------------------------------------------------------------------------------------------
# begin verwerking
#------------------------------------------------------------------------------------------------------------------------------------------

echo .
echo .
echo .
echo .

echo "Replace text in:"
echo .

#------------------------------------------------------------------------------------------------------------------------------------------

# een enkel bestand
ReplaceText

#------------------------------------------------------------------------------------------------------------------------------------------

echo .
echo .
echo klaar

#------------------------------------------------------------------------------------------------------------------------------------------
# einde verwerking
#------------------------------------------------------------------------------------------------------------------------------------------

Dit bestand moet uitvoerbaar worden gemaakt voor je het kan gebruiken.

Bij InputFile moet je het bestand invullen dat je wil veranderen.

In de functie ReplaceText moet je bij sed de zoektekst en de verangende tekst invullen.
Speciale tekens moeten speciaal worden behandeld. Aan het begin van het script staat ter herinnering aangegeven dat je die moet escapen met het backslash teken (\).

Laat het script uitvoeren in een terminal zodat je de uitvoer kan zien.
Gebruikersavatar
Mogenblue
Held
Held
Berichten: 351
Lid geworden op: Wo 18 Okt 2017, 08:27
Locatie: Amsterdam

Re: Script: Tekst vervangen in bestanden

Berichtdoor Mogenblue » Wo 11 Jan 2023, 20:45

Het tweede script vervangt de tekst in een reeks bestanden in 1 map.

Het bestand heet replace-text-in-map.sh en dit staat er in:

Code: Selecteer alles

#!/bin/bash

# replace text in files
#sed -i 's/source text/target text/g' "$InputFile"

# voor uitleg in terminal: man sed

# gebruik \n in sed om een nieuwe regel in te voegen

# speciale tekens escapen met \

# opdracht over meer regels uitspreiden met \

# probeer nieuwe vervanging eerst uit met 1 bestand. Als dat goed gaat kun je een hele map bewerken.

#------------------------------------------------------------------------------------------------------------------------------------------


FilePattern='*'
FilePattern='*.sh'
FilePattern='*.txt'

InputMap='/home/popeye/Documenten/texten/text map 1'


#------------------------------------------------------------------------------------------------------------------------------------------

# functie om tekst te vervangen in 1 bestand
ReplaceText () {

echo $InputFile
sed -i 's/source text/target text/g' "$InputFile"

}

#------------------------------------------------------------------------------------------------------------------------------------------
# begin verwerking
#------------------------------------------------------------------------------------------------------------------------------------------

echo .
echo .
echo .
echo .

echo "Replace text in:"
echo .

#------------------------------------------------------------------------------------------------------------------------------------------

# een hele map
echo $InputMap
cd "${InputMap}"
for InputFile in $FilePattern
do
ReplaceText
done

#------------------------------------------------------------------------------------------------------------------------------------------

echo .
echo .
echo klaar

#------------------------------------------------------------------------------------------------------------------------------------------
# einde verwerking
#------------------------------------------------------------------------------------------------------------------------------------------

Dit bestand moet uitvoerbaar worden gemaakt voor je het kan gebruiken.

Bij InputMap moet je de map invullen waar de bestanden in staan die je wil aanpassen.
Bij FilePattern kun je aangeven welke soort bestanden je wil verwerken. Er zijn drie voorbeelden gegeven. De laatste is degene die wordt gebruikt voor de verwerking.

Voordat je begint is het slim om eerst een kopie van je map te maken. Voer het dan met het eerste script eerst uit op 1 bestand om te kijken of je de zoek en vervang teksten goed hebt ingevoerd. Als dat goed werkt kun je de sed opdracht overzetten naar het script voor de map.
Als je de boel verprutst tijdens het stoeien met je bestanden kun je altijd weer de kopie terugzetten.

Je kunt de sed opdracht deactiveren door er een # teken voor te zetten. Als je dan het script in een terminal uitvoert zie je de bestanden langskomen die je met het FilePattern hebt geselecteerd.
Gebruikersavatar
Mogenblue
Held
Held
Berichten: 351
Lid geworden op: Wo 18 Okt 2017, 08:27
Locatie: Amsterdam

Re: Script: Tekst vervangen in bestanden

Berichtdoor Mogenblue » Wo 11 Jan 2023, 20:47

Het derde script vervangt de tekst in een reeks bestanden in een reeks mappen.

Het bestand heet replace-text-in-mappenlijst.sh en dit staat er in:

Code: Selecteer alles

#!/bin/bash

# replace text in files
#sed -i 's/source text/target text/g' "$InputFile"

# voor uitleg in terminal: man sed

# gebruik \n in sed om een nieuwe regel in te voegen

# speciale tekens escapen met \

# opdracht over meer regels uitspreiden met \

# probeer nieuwe vervanging eerst uit met 1 bestand. Als dat goed gaat kun je een hele map bewerken.

#------------------------------------------------------------------------------------------------------------------------------------------


FilePattern='*'
FilePattern='*.sh'
FilePattern='*.txt'

MappenLijst=(\
"/home/popeye/Documenten/texten/text map 1" \
"/home/popeye/Documenten/texten/text map 2" \
"/home/popeye/Documenten/texten/text map 3" \
"/home/popeye/Documenten/texten/text map 4" \
"/home/popeye/Documenten/texten/text map 5" \
)


#------------------------------------------------------------------------------------------------------------------------------------------

# functie om tekst te vervangen in 1 bestand
ReplaceText () {

echo $InputFile
sed -i 's/source text/target text/g' "$InputFile"

}

#------------------------------------------------------------------------------------------------------------------------------------------
# begin verwerking
#------------------------------------------------------------------------------------------------------------------------------------------

echo .
echo .
echo .
echo .

echo "Replace text in:"
echo .

#------------------------------------------------------------------------------------------------------------------------------------------

# een mappenlijst
for MapItem in "${MappenLijst[@]}"
do
echo $MapItem
cd "${MapItem}"
for InputFile in $FilePattern
do
ReplaceText
done
done

#------------------------------------------------------------------------------------------------------------------------------------------

echo .
echo .
echo klaar

#------------------------------------------------------------------------------------------------------------------------------------------
# einde verwerking
#------------------------------------------------------------------------------------------------------------------------------------------

Dit bestand moet uitvoerbaar worden gemaakt voor je het kan gebruiken.

Bij MappenLijst moet je de mappen invullen waar de bestanden in staan die je wil aanpassen. Voor de leesbaarheid is er één map per regel gebruikt. Door de backslash (\) kun je de opdracht over meer regels uitspreiden.
je kunt een reeks mappen gewoon in je bestandbeheerder selecteren en kopiëren en dan in dit script plakken. Je hoeft er dan alleen nog de quotes omheen te zetten en elke regel met een backslash afsluiten. Enkele quotes ipv dubbele mag ook. Probeer het maar.

Bij FilePattern kun je weer aangeven welke soort bestanden je wil verwerken. Er zijn drie voorbeelden gegeven. De laatste is degene die wordt gebruikt voor de verwerking.

Je kunt de sed opdracht deactiveren door er een # teken voor te zetten. Als je dan het script in een terminal uitvoert zie je de mappen en bestanden langskomen die verwerkt zouden worden.
Gebruikersavatar
Mogenblue
Held
Held
Berichten: 351
Lid geworden op: Wo 18 Okt 2017, 08:27
Locatie: Amsterdam

Re: Script: Tekst vervangen in bestanden

Berichtdoor Mogenblue » Vr 13 Jan 2023, 04:29

Voorbeeld tekst vervanging

Stel je hebt een verwijzing naar een initialisatie bestand die je in een aantal scripts gebruikt. Als je dat init bestand verplaatst naar een andere map moet je de verwijzing aanpassen in alle scripts die dat init bestand gebruiken.

Het initialisatie bestand is
/home/popeye/scripts/init-1.txt

En het wordt verplaatst naar
/home/popeye/scripts/init/init-1.txt


Wat je dan effectief moet veranderen is
scripts/init-1.txt

naar
scripts/init/init-1.txt

Als je het op deze manier doet en je zou de vervanging twee keer uitvoeren wordt de vervanging toch maar een keer uitgevoerd.

Want zodra
scripts/init-1.txt

is vervangen in
scripts/init/init-1.txt

zal
scripts/init-1.txt
niet meer te vinden zijn.


Als je de map scripts weglaat en
init-1.txt

vervangt naar
init/init-1.txt

en je dan het script twee keer uitvoert krijg je een ander resultaat namelijk
init/init/init-1.txt

En dan ben je je doel voorbij geschoten.



Het pad scheidingsteken, de forward slash, (/) is een speciaal teken. Voor sed moet je dan de volgende tekstreeksen gebruiken
zoektekst:
scripts\/init-1.txt

vervangtekst:
scripts\/init\/init-1.txt

De volledige sed opdracht wordt dan:
sed -i 's/zoektekst/vervangtekst/g' "$InputFile"
sed -i 's/scripts\/init-1.txt/scripts\/init\/init-1.txt/g' "$InputFile"


Andere speciale tekens die je ook moet escapen zijn quotes, dubbele quotes, slashes en backslashes:
'
"
/
\

wordt
\'
\"
\/
\\



Om een sed opdracht voor te bereiden kun je dus het beste de originele zoek en vervangtekst nemen,
dan een kopie maken en daar de escape tekens inzetten,
en als dat er goed uitziet dan de volledige teksten in de sed opdracht plaatsen.

zoektekst
scripts/init-1.txt

vervangtekst
scripts/init/init-1.txt


aangepaste zoektekst
scripts/init-1.txt
scripts\/init-1.txt

aangepaste vervangtekst
scripts/init/init-1.txt
scripts\/init\/init-1.txt


Dit soort dingen moet je altijd in een script voorbereiden. Als je dat rechtstreeks op de opdrachtregel in een terminal doet ga je vrijwel zeker fouten maken. En probeer het dan nog maar eens te herstellen....

Terug naar “Programmeren”

Wie is er online

Gebruikers op dit forum: Geen geregistreerde gebruikers en 1 gast