[erledigt] verständnisfrage sed

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
manes
Beiträge: 958
Registriert: 27.08.2007 11:26:54
Wohnort: Köln
Kontaktdaten:

[erledigt] verständnisfrage sed

Beitrag von manes » 18.03.2010 19:17:13

hallo,

statt desktop-applets für irgendwelche funktionen lege ich mir lieber einen prägnanten alias in die ~/.bashrc.
die akku-temperatur wird pseudogenau mit drei nachkommastellen angegeben: 30° werden mit 30000 angegeben. auslesen kann man mit

Code: Alles auswählen

echo "battery temperature:" $(cat /sys/devices/platform/smapi/BAT0/temperature|sed 's/.\{3\}$//')"°C"
battery temperature: 30°C
in meinem alias, der noch ein paar andere parameter abruft, funktioniert das kürzen der angabe um drei stellen aber nicht:

Code: Alles auswählen

alias bat='echo $(cat /sys/devices/platform/smapi/BAT0/cycle_count) "cycle counts" && echo "battery temperature:" $(cat /sys/devices/platform/smapi/BAT0/temperature|sed 's/.\{3\}$//')"°C" && echo "state:" $(cat /sys/devices/platform/smapi/BAT0/state) && echo $(cat /sys/devices/platform/smapi/BAT0/remaining_percent) "% remaining power"'

Code: Alles auswählen

bat
64 cycle counts
battery temperature: 30100°C
state: idle
94 % remaining power
was mache ich denn falsch? ist ja nichts wichtiges, ich verstünde es nur gern.
manes
Zuletzt geändert von manes am 18.03.2010 20:12:34, insgesamt 1-mal geändert.

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: verständnisfrage echo/ sed

Beitrag von gms » 18.03.2010 19:31:45

edit: diese Aussage ist falsch:
damit diese Regular Expression beim sed funktioniert, müßtest du auf die Extended Regular Expressions umschalten ( -r Option )


möglicherweise ist auch das Apostroph von der sed-Expression nicht korrekt escaped worden, ist das die Ausgabe von 'alias' oder so wie du das Kommando abgesetzt hast ?

Gruß
gms

Benutzeravatar
manes
Beiträge: 958
Registriert: 27.08.2007 11:26:54
Wohnort: Köln
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von manes » 18.03.2010 19:43:59

gms hat geschrieben:edit: diese Aussage ist falsch:
damit diese Regular Expression beim sed funktioniert, müßtest du auf die Extended Regular Expressions umschalten ( -r Option )
möglicherweise ist auch das Apostroph von der sed-Expression nicht korrekt escaped worden, ist das die Ausgabe von 'alias' oder so wie du das Kommando abgesetzt hast ?
danke für deine antwort, gms. welche aussage ist falsch?

nochmal: wenn ich

Code: Alles auswählen

echo "battery temperature:" $(cat /sys/devices/platform/smapi/BAT0/temperature|sed 's/.\{3\}$//')"°C"
in die konsole schreibe, kommt die antwort

Code: Alles auswählen

battery temperature: 29°C
exakt das gleiche steht im alias, den ich mit »bat« aufrufe. aber der sed-befehl wird ignoriert. warum?
manes

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: verständnisfrage echo/ sed

Beitrag von gms » 18.03.2010 19:55:12

die erste Anwort von mir war falsch
manes hat geschrieben: nochmal: wenn ich

Code: Alles auswählen

echo "battery temperature:" $(cat /sys/devices/platform/smapi/BAT0/temperature|sed 's/.\{3\}$//')"°C"
in die konsole schreibe, kommt die antwort

Code: Alles auswählen

battery temperature: 29°C
exakt das gleiche steht im alias, den ich mit »bat« aufrufe. aber der sed-befehl wird ignoriert. warum?
manes
dem muß ich leider nochmals nachgehen

Code: Alles auswählen

gms@gms1 ~ $ echo abcdef | sed 's/.\{3\}$//'
abc
funktioniert also

Code: Alles auswählen

gms@gms1 ~ $ alias test='echo abcdef | sed 's/.\{3\}$//''
gms@gms1 ~ $ test
abcdef
gms@gms1 ~ $ alias test
alias test='echo abcdef | sed s/.{3}$//'
ähnlich wie bei dir funktioniert das nicht, die Ausgabe von ' alias test' zeigt aber einen kleinen Unterschied

Code: Alles auswählen

gms@gms1 ~ $ alias test='echo abcdef | sed "s/.\{3\}$//"'
gms@gms1 ~ $ test
abc
das sed-Kommando richtig maskiert, funktionierts wieder


btw: so falsch war meine Antwort mit den Extended Regular Expressions auch nicht:

Code: Alles auswählen

gms@gms1 ~ $ alias test='echo abcdef | sed -r 's/.\{3\}$//''
gms@gms1 ~ $ test
abc
gms@gms1 ~ $ alias test
alias test='echo abcdef | sed -r s/.{3}$//'

Benutzeravatar
manes
Beiträge: 958
Registriert: 27.08.2007 11:26:54
Wohnort: Köln
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von manes » 18.03.2010 20:09:42

vielen dank. beim weg-probieren von möglichen fehlern mangelt es mir leider oft an sachkenntnis und/ oder phantasie...
manes

edit: verstanden hab ich es aber noch immer nicht. wer entfernt warum die hochkommata, die in der .bashrc den sed-befehl umgeben?

Benutzeravatar
Meillo
Moderator
Beiträge: 9253
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von Meillo » 18.03.2010 20:22:38

Nur so nebenbei: In diesem Fall wäre s/...$// sicher einfacher gewesen.

Dass es mit den EREs geht ist mehr Zufall. Hast du dir die Quotes mal genau angeschaut:
gms hat geschrieben:

Code: Alles auswählen

gms@gms1 ~ $ alias test='echo abcdef | sed -r 's/.\{3\}$//''
Das entspricht sowas:

Code: Alles auswählen

$ alias test=
'echo abcdef | sed -r '
s/.\{3\}$//
''
Wenn das sed-Kommando nicht mehr gequoted ist, dann werden die Backslashes von der Shell natürlich entfernt.

Wenn man die Sonderzeichen im sed-Programm entsprechend quoted, dann kann man auch ganz auf das Quoten des Programms an sich verzichten:

Code: Alles auswählen

alias foo='echo 30100 | sed s/...\$//'
Ansonsten Single- und Double-Quotes abwechseln.
Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 9253
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von Meillo » 18.03.2010 20:26:58

manes hat geschrieben: edit: verstanden hab ich es aber noch immer nicht. wer entfernt warum die hochkommata, die in der .bashrc den sed-befehl umgeben?
Den sed-Befehl umgeben gar keine Hochkommas. Das ist einmal das beendende Hochkomma des Strings davor und das beginnende des Strings danach. Siehe letzten Post von mir.
Use ed once in a while!

Benutzeravatar
manes
Beiträge: 958
Registriert: 27.08.2007 11:26:54
Wohnort: Köln
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von manes » 18.03.2010 20:58:25

Meillo hat geschrieben:Den sed-Befehl umgeben gar keine Hochkommas.
ok, den apostroph. ich meinte diese dinger (shift + #):
sed 's/.\{3\}$//'
manes

Benutzeravatar
Meillo
Moderator
Beiträge: 9253
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von Meillo » 18.03.2010 21:06:00

manes hat geschrieben:
Meillo hat geschrieben:Den sed-Befehl umgeben gar keine Hochkommas.
ok, den apostroph. ich meinte diese dinger (shift + #):
sed 's/.\{3\}$//'
manes
Ja, ich weiß, die meine ich auch.
Meillo hat geschrieben:Das ist einmal das beendende Hochkomma des Strings davor und das beginnende des Strings danach.
Die schließen das sed-Programm nicht ein, sondern aus.

Beispiel: 'foo'bar'baz'
bar ist nicht eingeschlossen, da es 'foo' -- bar -- 'baz' bedeutet.
Use ed once in a while!

Benutzeravatar
manes
Beiträge: 958
Registriert: 27.08.2007 11:26:54
Wohnort: Köln
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von manes » 18.03.2010 21:23:30

Meillo hat geschrieben:Ja, ich weiß, die meine ich auch.
manchmal fühle ich mich hier wie beim monopoly, wenn alle an einem vorbeiziehen und ich ohne 4000 mark zurück auf start muß.
hat jemand mal ein sed-tutorial for beginners zur hand? ich finde im netz nur anleitungen, die ähem nicht meinem niveau entsprechen... :?
manes

Benutzeravatar
Meillo
Moderator
Beiträge: 9253
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: verständnisfrage echo/ sed

Beitrag von Meillo » 18.03.2010 22:01:57

manes hat geschrieben:
Meillo hat geschrieben:Ja, ich weiß, die meine ich auch.
manchmal fühle ich mich hier wie beim monopoly, wenn alle an einem vorbeiziehen und ich ohne 4000 mark zurück auf start muß.
;-) Nur nicht verzweifeln.
hat jemand mal ein sed-tutorial for beginners zur hand? ich finde im netz nur anleitungen, die ähem nicht meinem niveau entsprechen... :?
Das betrifft nicht sed, sondern die Shell.

Du sagst der Shell

Code: Alles auswählen

alias foo='echo abcdef | sed -r 's/.\{3\}$//''
Die Shell sieht darin einen Befehl <alias> (dass das ein Builtin ist ist egal), und ein Argument <foo='echo abcdef | sed -r 's/.\{3\}$//''>. (Ich verwende die spitzen Klammern hier um die Codezeile zu begrenzen.)

Die Shell ruft also alias auf mit dem einen Argument. (Ob das wirklich genau so läuft weiß ich nicht, sollte aber irrelevant sein.) Das Argument wird aber zuvor von der Shell bearbeitet (d.h. Variablenexpansion, Historyexpansion, etc).

Der Reihe nach:
<foo=> ist uninteressant, da keines der Zeichen eine Sonderbedeutung für die Shell hat.
<'echo abcdef | sed -r '> ist ein String in Single-Quotes, somit wird er von der Shell eins zu eins übernommen. Quotes werden entfernt.
<s/.> sind Zeichen ohne Sonderbedeutung
<\{> die Escapesequenz wird ersetzt, durch die öffnende geschweifte Klammer
<3> ein normales Zeichen
<\}> die Escapesequenz wird ersetzt, durch die schließende geschweifte Klammer
<$//> es würde eine Variablenexpansion stattfinden, wenn $/ oder $// eine gültige Variable wäre. Da das nicht so ist wird's einfach übernommen.
<''> ist ein leerer String. Quotes werden entfernt.

Heraus kommt der eine String: <foo=echo abcde | sed -r s/.{3}$//>. (Dass alias den Teil nach dem Gleichheitszeichen in Single-Quotes einfasst ist eine Sache der Darstellung. Wenn du es mit Variablen testest, dann ist es wie erwartet.)


Siehst du nun, dass das sed-Kommando *nicht* in Single-Quotes eingeschlossen ist, sondern von ihnen ausgeschlossen ist?

Du denkst bislang immer an den Fall "foo'bar'baz", da ist bar eingeschlossen, in 'foo'bar'baz' aber nicht.



btw: 2000 Posts ;-)
Use ed once in a while!

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: [erledigt] verständnisfrage sed

Beitrag von gms » 18.03.2010 22:10:20

das hier auftretende Problem hat aber eigentlich nichts mit sed zu tun, die von dir vermißten Apostroph-Zeichen werden durch die Shell entfernt
Beweis: Bei diesem Kommando wird sed nicht einmal aufgerufen:

Code: Alles auswählen

gms@gms1 ~ $ echo 'echo abcdef | sed ' s/.\{3}\$//''
echo abcdef | sed  s/.{3}$//
gms@gms1 ~ $
Die Shell interpretiert das als drei Zeichenketten, die an das echo-Kommando übergeben werden:
1: 'echo abcdef | sed '
2: s/.\{3}\$//
3: ''
Du müßtest also der Shell irgendwie "mitteilen", daß das Ende der ersten Zeichenkette nicht nach dem 'sed' aufhört, das geht aber bei den Zeichenketten die mit Apostroph gequotet wurden nicht ( das sogenannte Escapen mittels dem \-Zeichen funktioniert hier nicht )
Du kannst aber dort auch ohne weiteres die Doppel-Hochkomma verwenden:

Code: Alles auswählen

gms@gms1 ~ $ echo 'echo abcdef | sed "s/.\{3}\$//"'
echo abcdef | sed "s/.\{3}\$//"
Ich hoffe damit wird das zumindest ein bißchen verständlicher

Gruß
gms

edit:
@Meillo
nachdem ich schon so lange an dieser Erklärung getippt habe, wollte ich sie zumindest auch noch posten

Benutzeravatar
Meillo
Moderator
Beiträge: 9253
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [erledigt] verständnisfrage sed

Beitrag von Meillo » 18.03.2010 22:27:34

gms hat geschrieben: edit:
@Meillo
nachdem ich schon so lange an dieser Erklärung getippt habe, wollte ich sie zumindest auch noch posten
Verständlich.


Nachdem ich nachgedacht habe, kann ich jetzt auch erklären warum folgendes Verhalten so ist:

Code: Alles auswählen

$ echo 'foo\'bar\'baz'
> '
foo\bar'baz

Innerhalb von Single-Quotes wird jedes Zeichen literal genommen, auch der Backslash. Somit ist das Argument:
<'foo\'> ein String der eins zu eins übernommen wird. Die Quotes werden entfernt.
<bar> Zeichen ohne Sonderbedeutung
<\'> eine Escapesequenz die durch ein Hochkomma ersetzt wird
<baz> Zeichen ohne Sonderbedeutung
<'> der Beginn eines Strings in Single-Quotes. Das abschließende Quote fehlt, deshalb kommt der sekundäre Prompt.


Bei Double-Quotes ist das anders, da dort Backlashes als Escapezeichen gewertet werden:

Code: Alles auswählen

$ echo "foo\"bar\"baz"
foo"bar"baz
Use ed once in a while!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: [erledigt] verständnisfrage sed

Beitrag von Duff » 19.03.2010 07:54:52

Einfach unschlagbar, wenn es um sed oder awk geht!

...man lernt nie aus...
Oh, yeah!

Antworten