bash problem mit variablensubstitution in bc

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:

bash problem mit variablensubstitution in bc

Beitrag von manes » 14.07.2016 19:46:17

halo forum,
jedenfalls glaube ich, daß der titel eine gültige annäherung an das problem darstellt.
ich benutze ein längliches script, das als unterstützung für die encodierung von videos dienen soll.
teil dieses scriptes ist eine unschöne lange zeile, die, als bashscript mit initialisierten variablen, die gewünschten ergebnisse auswirft:

Code: Alles auswählen

echo "interleave(a,b,a,c,a,d,a,e,a,f,a,g,a,h,a,i,a,j,a,k,a,l,a,m,a,n,a,o,a,p,a,q,a,r,a,s,a,t,a,u,a,v,a,w,a,x,a,y,a,z,a,aa,a,ab,a,ac,a,ad,a,ae,a,af,a,ag,a,ah,a,ai,a,aj,a,ak,a,al,a,am,a,an,a,ao,a,ap,a,aq,a,ar,a,as,a,at,a,au,a,av,a,aw,a,ax,a,ay,a,az,a,ba,a,bb,a,bc,a,bd,a,be,a,bf,a,bg,a,bh,a,bi,a,bj,a,bk,a,bl,a,bm,a,bn,a,bo,a,bp,a,bq,a,br,a,bs,a,bt,a,bu,a,bv,a,bw,a,bx,a,by,a,bz,a,ca,a,cb,a,cc,a,cd,a,ce,a,cf,a,cg,a,ch,a,ci,a,cj,a,ck,a,cl,a,cm,a,cn,a,co,a,cp,a,cq,a,cr,a,cs,a,ct,a,cu,a,cv,a,cw,a,cx,a,cy,a,cz,a,da,a,db,a,dc,a,dd,a,de,a,df,a,dg,a,dh,a,di,a,dj,a,dk,a,dl,a,dm,a,dn,a,do,a,dp,a,dq,a,dr,a,ds,a,dt,a,du,a,dv,a,dw,a,dx,a,dy,a,dz,a,ea,a,eb,a,ec,a,ed,a,ee,a,ef,a,eg,a,eh,a,ei,a,ej,a,ek,a,el,a,em,a,en,a,eo,a,ep,a,eq,a,er,a,es,a,et,a,eu,a,ev,a,ew,a,ex,a,ey,a,ez,a)"|cut -d',' --complement -f $(echo $(cat "${source1%.*}".$2.aqpsy.avs|wc -l) *2 -1|bc)-310
der text wird, abhängig von der zeilenzahl in ${source1%.*}".$2.aqpsy.avs, gekürzt ausgegeben. wenn die andere datei sieben zeilen umfasst, ist der output:

Code: Alles auswählen

interleave(a,b,a,c,a,d,a,e,a,f,a,g,a)
das soll so.
im länglichen script ist der output seit einer neuinstallation (vorher: testing, jetzt stable) stets vorher kam das gelegentlich, ohne mir erkennbares muster, jetzt stets vor.
die einzige fehlermeldung im terminal ist

Code: Alles auswählen

(standard_in) 1: syntax error
(standard_in) 1: illegal character: L
(standard_in) 1: syntax error
ich vermute, daß bc einen unzulässigen input bekommt, also "cat "${source1%.*}".$2.aqpsy.avs|wc -l" den fehler wirft.
die datei, die cat aufruft, existiert und enthält eine anzahl zeilen.
blöde frage, vielleicht: wie kann ich den fehler denn einkreisen?
wer dieses script sehen möchte:
script auf github
Sometimes you have a programming problem and it seems like the best solution is to use regular expressions; now you have two problems.
David Mertz

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: bash problem mit variablensubstitution in bc

Beitrag von Phineas » 15.07.2016 04:20:20

Wozu bc (und cat)?

Code: Alles auswählen

echo "interleave(a,b,a,c,a,d,a,e,a,f,a,g,a,h,a,i,a,j,a,k,a,l,a,m,a,n,a,o,a,p,a,q,a,r,a,s,a,t,a,u,a,v,a,w,a,x,a,y,a,z,a,aa,a,ab,a,ac,a,ad,a,ae,a,af,a,ag,a,ah,a,ai,a,aj,a,ak,a,al,a,am,a,an,a,ao,a,ap,a,aq,a,ar,a,as,a,at,a,au,a,av,a,aw,a,ax,a,ay,a,az,a,ba,a,bb,a,bc,a,bd,a,be,a,bf,a,bg,a,bh,a,bi,a,bj,a,bk,a,bl,a,bm,a,bn,a,bo,a,bp,a,bq,a,br,a,bs,a,bt,a,bu,a,bv,a,bw,a,bx,a,by,a,bz,a,ca,a,cb,a,cc,a,cd,a,ce,a,cf,a,cg,a,ch,a,ci,a,cj,a,ck,a,cl,a,cm,a,cn,a,co,a,cp,a,cq,a,cr,a,cs,a,ct,a,cu,a,cv,a,cw,a,cx,a,cy,a,cz,a,da,a,db,a,dc,a,dd,a,de,a,df,a,dg,a,dh,a,di,a,dj,a,dk,a,dl,a,dm,a,dn,a,do,a,dp,a,dq,a,dr,a,ds,a,dt,a,du,a,dv,a,dw,a,dx,a,dy,a,dz,a,ea,a,eb,a,ec,a,ed,a,ee,a,ef,a,eg,a,eh,a,ei,a,ej,a,ek,a,el,a,em,a,en,a,eo,a,ep,a,eq,a,er,a,es,a,et,a,eu,a,ev,a,ew,a,ex,a,ey,a,ez,a)"|cut -d',' --complement -f $(($(wc -l < "${source1%.*}".$2.aqpsy.avs)*2-1))-310

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

Re: bash problem mit variablensubstitution in bc

Beitrag von Meillo » 15.07.2016 16:35:42

manes hat geschrieben:

Code: Alles auswählen

echo "interleave(a,b,a,c,a,d,a,e,a,f,a,g,a,h,a,i,a,j,a,k,a,l,a,m,a,n,a,o,a,p,a,q,a,r,a,s,a,t,a,u,a,v,a,w,a,x,a,y,a,z,a,aa,a,ab,a,ac,a,ad,a,ae,a,af,a,ag,a,ah,a,ai,a,aj,a,ak,a,al,a,am,a,an,a,ao,a,ap,a,aq,a,ar,a,as,a,at,a,au,a,av,a,aw,a,ax,a,ay,a,az,a,ba,a,bb,a,bc,a,bd,a,be,a,bf,a,bg,a,bh,a,bi,a,bj,a,bk,a,bl,a,bm,a,bn,a,bo,a,bp,a,bq,a,br,a,bs,a,bt,a,bu,a,bv,a,bw,a,bx,a,by,a,bz,a,ca,a,cb,a,cc,a,cd,a,ce,a,cf,a,cg,a,ch,a,ci,a,cj,a,ck,a,cl,a,cm,a,cn,a,co,a,cp,a,cq,a,cr,a,cs,a,ct,a,cu,a,cv,a,cw,a,cx,a,cy,a,cz,a,da,a,db,a,dc,a,dd,a,de,a,df,a,dg,a,dh,a,di,a,dj,a,dk,a,dl,a,dm,a,dn,a,do,a,dp,a,dq,a,dr,a,ds,a,dt,a,du,a,dv,a,dw,a,dx,a,dy,a,dz,a,ea,a,eb,a,ec,a,ed,a,ee,a,ef,a,eg,a,eh,a,ei,a,ej,a,ek,a,el,a,em,a,en,a,eo,a,ep,a,eq,a,er,a,es,a,et,a,eu,a,ev,a,ew,a,ex,a,ey,a,ez,a)"|cut -d',' --complement -f $(echo $(cat "${source1%.*}".$2.aqpsy.avs|wc -l) *2 -1|bc)-310
der text wird, abhängig von der zeilenzahl in ${source1%.*}".$2.aqpsy.avs, gekürzt ausgegeben. wenn die andere datei sieben zeilen umfasst, ist der output:

Code: Alles auswählen

interleave(a,b,a,c,a,d,a,e,a,f,a,g,a)
Beim eigentlichen Problem kann ich leider nicht weiterhelfen, aber dieses haarstraeubende ``interleave(a,b,a,c,...)'' hat mich doch beschaeftigt. So eine Folge will man nicht hinschreiben, sondern generieren. Die Frage ist also, wie man das mit Unix am besten macht.

seq(1) kann leider nur Zahlen generieren ... aber split(1) generiert Dateinamen in der Art. Ueber Hilfsdateien kann man die Sequenz erzeugen:

Code: Alles auswählen

tempdir="`mktemp -d`"
cd "$tempdir"
split -n 26 -a1  /dev/null ''
split -n `expr 26 \* 5` -a2  /dev/null ''
interleave="`(ls ?;ls ??) | tr \\n , | sed 's/,/,a,/g;s/^a,//;s/,$//'`"
cd -
rm -rf "$tempdir"
Aber natuerlich ist es unschoen, Dateien zu erzeugen, nur um deren Namen zu lesen. Darum noch eine zweite Variante, welche die Sequenz direkt generiert:

Code: Alles auswählen

genseq() {
	letters="a b c d e f g h i j k l m n o p q r s t u v w x y z"
	for i in '' $letters; do
		for j in $letters; do
			echo "$i$j"
		done
	done
}
interleave="`genseq | sed '1d;s/^/a,/' | head -n \`wc -l <$otherfile\` | xargs echo | tr ' ' ,`"
(Habe genseq() bewusst moeglichst generisch gehalten.)


Was ich noch nicht verstanden habe ist die Seltsamkeit der Sequenz. Warum wird ``,a,'' als Trenner verwendet und nicht nur das Komma? Warum beginnt sie nicht mit ``a,a,b,a,''? Warum hat's am Anfang und am Ende einen `a'-Trenner? Das wird vermutlich in fachlichen Anforderungen begruendet sein. Allerdings kommt mir das bisherige Vorgehen dieses kurzen Codeabschnitts logisch gesehen wenig straight-forward vor. Das laesst vermuten, dass auch die Sequenz komplizierter als noetig ist ... aber das sind nur Mutmassungen. Ich habe mir das ``laengliche Script'' auch gar nicht durchgelesen, hab mir nur den zitierten kurzen Codeabschnitt vorgenommen.
Use ed once in a while!

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: bash problem mit variablensubstitution in bc

Beitrag von Phineas » 15.07.2016 17:13:33

Da eh die Bash benutzt wird, kann man es einfach per Brace Expansion erzeugen:

Code: Alles auswählen

echo "interleave($(printf %s, a,{b..z} a,{a..e}{a..z})a)"
Komplett also:

Code: Alles auswählen

echo "interleave($(printf %s, a,{b..z} a,{a..e}{a..z})a)" | cut -d ',' --complement -f $(($(wc -l < "${source1%.*}".$2.aqpsy.avs)*2-1))-310

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

Re: bash problem mit variablensubstitution in bc

Beitrag von manes » 15.07.2016 20:14:06

Phineas hat geschrieben:Wozu bc (und cat)?
ööööhm, weil ich es nicht besser weiß. wo ist das unglücklich-guck-und-schulter-zuck-emoji?
Phineas hat geschrieben: Da eh die Bash benutzt wird, kann man es einfach per Brace Expansion erzeugen:(…)
das hab ich gesucht! diese lange zeile war mir sowas von peinlich. danke für diese hilfe. (und gleich nebenan hab ich sogar sowas ähnliches benutzt, so ein stückchen code von stackoverflow, ohne die logik kapiert zu haben…
Meillo hat geschrieben:Was ich noch nicht verstanden habe ist die Seltsamkeit der Sequenz. Warum wird ``,a,'' als Trenner verwendet und nicht nur das Komma? Warum beginnt sie nicht mit ``a,a,b,a,''? Warum hat's am Anfang und am Ende einen `a'-Trenner? Das wird vermutlich in fachlichen Anforderungen begruendet sein. Allerdings kommt mir das bisherige Vorgehen dieses kurzen Codeabschnitts logisch gesehen wenig straight-forward vor. Das laesst vermuten, dass auch die Sequenz komplizierter als noetig ist ... aber das sind nur Mutmassungen. Ich habe mir das ``laengliche Script'' auch gar nicht durchgelesen, hab mir nur den zitierten kurzen Codeabschnitt vorgenommen.
ach, ich beschäftige mich ein wenig mit videoencoding, und da führt leider kaum ein weg an der windowswelt vorbei. ich benutze dafür u.a. avisynth und AvsPmod unter wine, die dafür unverzichtbar sind. verschiedene videosequenzen werden mit verschiedenen parametern encodiert und am ende fällt eine liste raus, und man kann das frame der source (a) jeweils mit dem encodierten frame (b,c,…) unmittelbar vergleichen. und das längliche script hat leider durchgehend eine qualität, die meinen bash- und generellen "programmier"kenntnissen entspricht, räusper. für mich reichts, meistens und irgendwie.

vielen dank euch allen wieder einmal! :THX:
Sometimes you have a programming problem and it seems like the best solution is to use regular expressions; now you have two problems.
David Mertz

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: bash problem mit variablensubstitution in bc

Beitrag von rendegast » 15.07.2016 20:15:25

manes hat geschrieben:

Code: Alles auswählen

echo $(cat "${source1%.*}".$2.aqpsy.avs|wc -l) *2 -1|bc
Das '*' macht hier Probleme, Bsp.:

Code: Alles auswählen

# echo 2 * 5 | bc
(standard_in) 1: illegal character: L
(standard_in) 1: illegal character: O
(standard_in) 1: illegal character: K
(standard_in) 1: syntax error
(standard_in) 1: illegal character: L
(standard_in) 1: illegal character: M
(standard_in) 1: illegal character: M
Der an 'bc' übergebene Ausdruck muß gequotet werden.

Code: Alles auswählen

# echo '2 * 5' | bc
10
# echo "2 * 5" | bc
10
Doppelquotes, damit die eingeschlossenen Subshell noch ausgeführt wird:

Code: Alles auswählen

echo "$(cat "${source1%.*}".$2.aqpsy.avs|wc -l) *2 -1"|bc


-------------------------------------------------
Phineas hat geschrieben: Wozu bc (und cat)?
'bc' rechnet total gut, und $(< blafoo) ist ein bashism - nix posix.

-------------------------------------------------
EDIT typos korrigiert
(habe mehrere Flaschen prosecco/leer hier herumstehen)
Zuletzt geändert von rendegast am 15.07.2016 21:55:08, insgesamt 3-mal geändert.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

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

Re: bash problem mit variablensubstitution in bc

Beitrag von Meillo » 15.07.2016 21:40:39

Phineas hat geschrieben:Da eh die Bash benutzt wird, kann man es einfach per Brace Expansion erzeugen:

Code: Alles auswählen

echo "interleave($(printf %s, a,{b..z} a,{a..e}{a..z})a)"
Das stimmt natuerlich. (Ist nur nicht meine Welt.)


manes hat geschrieben: ach, ich beschäftige mich ein wenig mit videoencoding [...] verschiedene videosequenzen werden mit verschiedenen parametern encodiert und am ende fällt eine liste raus, und man kann das frame der source (a) jeweils mit dem encodierten frame (b,c,…) unmittelbar vergleichen.
Danke fuer die Erklaerung.


rendegast hat geschrieben:
manes hat geschrieben:

Code: Alles auswählen

echo $(cat "${source1%.*}".$2.aqpsy.avs|wc -l) *2 -1|bc
Das '*' macht hier Probleme, Bsp.:

Code: Alles auswählen

# echo 2 * 5 | bc
(standard_in) 1: illegal character: L
(standard_in) 1: illegal character: O
(standard_in) 1: illegal character: K
(standard_in) 1: syntax error
(standard_in) 1: illegal character: L
(standard_in) 1: illegal character: M
(standard_in) 1: illegal character: M
Der an 'bc' übergeben Ausdruck muß gequotet werden.
Treffer! Jetzt, wo du's sagst, seh' ich's auch. ;-)

Ich denke, es reicht ein Backslash vor dem Stern.

rendegast hat geschrieben:
Phineas hat geschrieben: Wozu bc (und cat)?
'bc rechnet total gut, und $(< blafoo)' ist ein bashisnm - nix posix.
Aber $(wc -l <blafoo) ist keiner. :P
Use ed once in a while!

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: bash problem mit variablensubstitution in bc

Beitrag von Phineas » 16.07.2016 04:15:47

rendegast hat geschrieben:... nix posix.
Wenn da bash im Shebang steht, ist mir Posix völlig schnuppe. ;)

Antworten