Fabian-Haas
Anmeldungsdatum: 8. Januar 2014
Beiträge: 4
|
Hallo, dies ist meine erste Frage hier, ich bitte also zu entschuldigen, wenn ich irgendetwas falsch machen sollte, und mir das zu sagen 😉. Ich habe folgendes Problem: Ich möchte mithilfe eines shell-scripts einen bestimmten textabschnitt der sich über mehrere Zeilen hinwegzieht aus einer datei löschen. Konkret handelt es sich dabei um die smb.conf (Samba-Konfigurationsdatei), zu der ich zwar Einträge für neue Freigaben hinzufügen, jedoch keine löschen kann. Freigaben werden dabei immer nach dem selben Schema angelegt, sodass sie auch gleich zu löschen sein müssten. Hier der relevante Abschnitt aus der Datei (zum Beispiel mit den Freigaben "jugend forscht", "jugen-forscht" und "jugend-forscht"): [jugend forscht]
comment = jugend forscht
path = /home/jugend forscht
admin users = @jugend forscht
read only = No
create mask = 0770
directory mask = 0770
[jugen-forscht]
comment = jugen-forscht
path = /home/jugen-forscht
admin users = @jugen-forscht
read only = No
create mask = 0770
directory mask = 0770
[jugend-forscht]
comment = jugend-forscht
path = /home/jugend-forscht
admin users = @jugend-forscht
read only = No
create mask = 0770
directory mask = 0770 Mein erster Ansatz war den jeweiligen Eintrag mithilfe des Befehls "tr" zu suchen und mit "nichts" zu ersetzen, jedoch bekam ich dabei die Fehlermeldung, dass man nicht etwas mit einer leeren Menge ersetzen könne.
Meine zweite Idee sah dann so aus, : 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | #!/bin/bash -
echo ""
echo " ----------------------"
echo " - -"
echo " - Freigabe löschen -"
echo " - -"
echo " ----------------------"
echo ""
echo ""
echo ""
# deklariert die Variable "FREIGABE"
echo " Bitte geben Sie den den Namen der zu löschenden Freigabe ein: "
read FREIGABE
# gibt die Variable "FREIGABE" an
echo " festgelegter Namen der zu löschenden Freigabe: $FREIGABE"
# löscht den Ordner der Freigabe
rm -r -f /home/$FREIGABE
# löscht den Eintrag der Freigabe in der "smb.conf"
ZEILE=$(egrep -n "[$FREIGABE]" /etc/samba/smb.conf | cut -d: -f1)
ZEILE2=$[$ZEILE+7]
sed '$ZEILE,$ZEILE2 d' /etc/samba/smb.conf
# wartet 10 Sekunden und löscht den Bildschirminhalt
sleep 10
tput clear
|
Dabei sollte, so die Idee, die Zeilennummer des Namens der zu löschenden Freigabe mit dem Befehl "egrep" ermittelt und in der Variablen $ZEILE gespeichert werden. Da daraufhin immer die gleiche Anzahl Zeilen (7) folgt, sollte die Zeilennummer der letzen Zeile der Freigabe in der Variable $ZEILE2 gespeichert werden. Mit dem Befehl "sed" sollten daraufhin alle Zeilen von der ersten bis zu letzen der Freigabe gelöscht werden. Leider kamen dabei nur noch mehr Fehlermeldungn und es klappte nicht 😕.
Vielleicht kennt jemand dieses Problem, bzw. hat einen Lösungsansatz dafür. Mit freundichen Grüßen und vielen Dank im vorraus
Fabian Haas Anmerkung: das shell-script soll auf jedem linux-system (insbesondere auf einem ipfire) funktionieren!
|
diesch
Anmeldungsdatum: 18. Februar 2009
Beiträge: 5072
Wohnort: Brandenburg an der Havel
|
Herzlich willkommen hier im Forum! ☺ Ansatz: Gehe die Datei Zeilenweise durch und merke dir, ob du gerade in einem Abschnitt bist, den du löschen willst. Wenn nicht, gib die Zeile aus. Das lässt sich ohne externe Programme nur mit der POSIX Bourne-Shell machen, und sollte daher überall laufen (ich habe es aber eher nicht so ausführlich getestet 😉 ): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | #!/bin/sh
FREIGABE='jugen-forscht'
INPUT='smb.conf'
START=" [$FREIGABE]"
END=' directory mask = 0770 '
IFS='
' # sonst schluckt read Leerzeichen
is_deleting=''
while read line; do
case "$line" in
"$START") test -z "$is_deleting" && is_deleting=yes;;
"$END") test -z "$is_deleting" || is_deleting='';;
*) test -z "$is_deleting" && echo "$line"
esac
done < "$INPUT"
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Hi Fabian, auch von mir ein herzliches "Willkommen" hier auf dem Forum ! Solch einen Abschnitt zu löschen geht recht elegant mit sed, wenn Du einen Adressbereich von ... bis benutzt: sed "/^ *\[jugend-forscht\]/,// d" /etc/samba/smb.conf (hier: von der Überschrift bis zur leeren Zeile) → siehe im sed- Tutorium LG, track
|
diesch
Anmeldungsdatum: 18. Februar 2009
Beiträge: 5072
Wohnort: Brandenburg an der Havel
|
track schrieb: Solch einen Abschnitt zu löschen geht recht elegant mit sed, wenn Du einen Adressbereich von ... bis benutzt:
Das kann Probleme machen, wenn der Name Zeichen mit besonderer Bedeutung in regulären Ausdrücken enthält, z.B. jugend.forscht
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Mehreres, teils abweichend von Tracks Empfehlung:
| token=jugen-forscht ; sed -i "/\["${token}"]/,+8d" smb.conf
|
Die Variable ${token} darf nicht in Anführungszeichen stehen, um von der Shell interpretiert zu werden. Die Eckige Klammer muss maskiert, geschützt, versteckt werden, damit Sed das nicht als Zeichengruppe interpretiert. Um keine zusätzlichen Leerzeilen zu sammeln muss man 8 Zeilen löschen, scheint mir. Das tut +8, welches keine absolute Zeile adressiert, sondern relativ. Wusste gar nicht dass das geht, dachte so wäre es praktisch und - voila! Mit sed -i wird die Datei in Place verändert. Sonst geschieht nur eine Ausgabe der veränderten Datei auf stdout. Ein Nogo ist sleep 8, tput clear. Näheres dazu bei der Koryphäe: http://www.catb.org/~esr/writings/taoup/html/
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
diesch schrieb: track schrieb: Solch einen Abschnitt zu löschen geht recht elegant mit sed, wenn Du einen Adressbereich von ... bis benutzt:
Das kann Probleme machen, wenn der Name Zeichen mit besonderer Bedeutung in regulären Ausdrücken enthält, z.B. jugend.forscht
Hier mal eine andere Art das Problem mit den Zeichen zu umgehen: | token='was auch immer.'
awk -v "SEP=$token" '{p=1}; ($1 == SEP),/^\s*$/{p=0}; {if (p==1) print $0}' /etc/samba/smb.conf
|
☺ Das ganze sieht so kompliziert aus, weil ich keine andere Möglichkeit gefunden habe, die Range zu invertieren. Ciao robert
|
Fabian-Haas
(Themenstarter)
Anmeldungsdatum: 8. Januar 2014
Beiträge: 4
|
Erst einmal vielen Dank für die vielen hilfreichen Antworten und die herzliche Aufnahme ins Forum 😀. Leider hatte ich vorher nicht die Zeit die Ratschläge zu testen und antworten. Ich habe jetzt der Einfachheit halber, jetzt den Befehl | token=jugen-forscht ; sed -i "/\["${token}"]/,+8d" smb.conf
|
genommen. Dank aber auch an die anderen Anregungen, sie haben mir wieder einmal geholfen ein bisschen dazu zulernen 😉.
Der obrige Befehl klappt auch super ☺. Mich würde nochmal interessieren, warum sleep 8, tput clear so ein no-go sein soll ? 😳 Vielen Dank
Fabian Haas
|
Fabian-Haas
(Themenstarter)
Anmeldungsdatum: 8. Januar 2014
Beiträge: 4
|
Leider habe ich jetzt folgendes Problem 😉: Ich kann zwar nun einen bestimmten mehrzeiligen Textabschnitt aus einer Datei löschen, wie tu ich das jetzt aber mit einem nur einzeiligen. Ich will also im Grunde genommen nun eine einzelne bestimmte Zeile aus einer Datei löschen. Ich dachte das hier: | token=jugen-forscht ; sed -i "/\"${token}"/,+0d" smb.conf
|
würde funktionieren (extra ohne dies '[...]' Klammern, diese sind in der Zieldatei nicht vorhanden), tut es jedoch leider nicht, sondern ich bekomme die Fehlermeldung | sed: -e Ausdruck #1, Zeichen 21: Zusätzliche Zeichen nach dem Befehl
|
. Schon einmal Danke im vorraus; ich freue mich über jede Idee/Anregung. 😀 Mfg Fabian Haas
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Fabian-Haas schrieb: ... Ich kann zwar nun einen bestimmten mehrzeiligen Textabschnitt aus einer Datei löschen, wie tu ich das jetzt aber mit einem nur einzeiligen.
Du hast auch nicht in das sed- Manual 'reingeguckt, das ich Dir ober verlinkt hatte, nee ? 😉 Da steht das nämlich gleich als allererstes Beispiel drin ... LG, track
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Fabian-Haas schrieb:
Mich würde nochmal interessieren, warum sleep 8, tput clear so ein no-go sein soll ? 😳
Das zwingt den Verwender sich den Output anzuschauen, und zwar in den ersten 8 Sekunden. Das wird meistens zu viel sein und selten zu wenig. Usus bei Linux ist, den Bilschirm nicht zu löschen. Es tut niemand weh, wenn der Output so lange dasteht bis man weitere Kommandos eingegeben hat, und der Text rausgescrollt ist; soweit rausgescrollt, dass er auch im Puffer nicht mehr verfügbar ist. Auch kann es sein dass Dein Output gar nicht interessant ist, sondern der davor. Womöglich will man den Output irgendwohin mailen, dann ist es auch praktisch, wenn er noch auf dem Bildschirm steht.
|
Fabian-Haas
(Themenstarter)
Anmeldungsdatum: 8. Januar 2014
Beiträge: 4
|
Hallo Es hat nun alles geklappt, thx nochmal an alle. ☺ Mfg
Fabian Haas
|
bluestar
Anmeldungsdatum: 13. Februar 2016
Beiträge: 24
|
Hallo Leute Ich hätte dazu auch mal eine Frage, wäre es nicht sinnvoller anstatt zu löschen
das ganz erstmal auszuschalten in dem man dort # Zeichen davor setzt? So kann man das jederzeit wieder einschalten wenn man es braucht.
| alt:
token=jugen-forscht ; sed -i "/\["${token}"]/,+8d" smb.conf
|
| neu:
token=jugen-forscht ; sed -i "s/\["${token}"]/'#',+8d" smb.conf
|
das sollte dann doch ähnlich gehen oder? Gruß Dennis
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Der Befehl dürfte dann aber kein 'd' für 'delete' mehr beinhalten, sondern sollte die betreffenden Zeilen (.*) durch "# " und die alte Zeile ersetzen. Das -i für inplace habe ich weggelassen, um zu sehen, ob es klappt, und -r eingefügt, um die runden Klammern nicht maskieren zu müssen.
| token=jugen-forscht ; sed -r "/\["${token}"]/,+8s/(.*)/# &/" smb.conf
|
|
bluestar
Anmeldungsdatum: 13. Februar 2016
Beiträge: 24
|
user_unknown schrieb: Der Befehl dürfte dann aber kein 'd' für 'delete' mehr beinhalten, sondern sollte die betreffenden Zeilen (.*) durch "# " und die alte Zeile ersetzen. Das -i für inplace habe ich weggelassen, um zu sehen, ob es klappt, und -r eingefügt, um die runden Klammern nicht maskieren zu müssen.
| token=jugen-forscht ; sed -r "/\["${token}"]/,+8s/(.*)/# &/" smb.conf
|
Wenn das geht eine schöne Lösung, wie geschrieben, ich denke sinn macht eher etwas mal
in einer Freigabe auszuschalten, löschen würde ich die eher nicht, ich denke der Ansatz
war hier das in ein Script zu setzen, aber dann könnte man das Script nur einmal nutzen
wenn man eine Freigabe löscht. Ich würde jetzt nur nicht verstehen wie man das Rüchgängig macht
von der Logik würde ich dann das so setzen:
| token=jugen-forscht ; sed -r "/\#["${token}"]/,+8d/(.*)/# &/" smb.conf
|
Damit die Zeile gefunden wird und d sollte ja dann das # löschen, aber
warscheinlich liege ich dann wieder Falsch oder? Aber deine Lösung oben
hast du sehr gut erklärt. Gruß Dennis
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
bluestar schrieb: Ich würde jetzt nur nicht verstehen wie man das Rüchgängig macht
von der Logik würde ich dann das so setzen:
| token=jugen-forscht ; sed -r "/\#["${token}"]/,+8d/(.*)/# &/" smb.conf
|
Durch Raten wirst Du sed nicht lernen können. Dazu brauchst Du ein Tutorial oder eine Referenz und musst fleißig ausprobieren und lernen.
|