KeyzerSoze
Anmeldungsdatum: 28. September 2014
Beiträge: 120
|
Hallo, hier ist ein kurzes Skript: (
for i in {50..150}
do
echo ""$i".txt"
done
) > meinekonfigurationsdatei.in
Das liefert als Ausgabe:
50.txt
51.txt
...
100.txt
...
150.txt Ich möchte aber folgende Ausgabe:
050.txt
051.txt
...
100.txt
...
150.txt Kurz gesagt, es geht mir um die "0" vor den Zahlen unter 100. Kann mir jemand weiterhelfen? Vielen Dank im Voraus!
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11250
Wohnort: München
|
Du kannst einfach angeben, dass er von 050 bis 150 zählen soll:
(
for i in {050..150}
do
echo ""$i".txt"
done
) > meinekonfigurationsdatei.in
|
KeyzerSoze
(Themenstarter)
Anmeldungsdatum: 28. September 2014
Beiträge: 120
|
Ja, danke schon mal.
Sorry, ich habe die Frage leider schlampig gestellt. Ich habe statt
for i in {50..150}
folgendes in meinem Skript stehen: for i in $(eval echo "{$startzahl .. $endzahl}")
und da kommt es vor, dass echo "$startzahl"<100 und echo "$endzahl">100 .
Die Variablen startzahl und endzahl lese ich mit read ein.
Ich fürchte, ich komme ohne if-Schleife nicht weiter, oder?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11250
Wohnort: München
|
Man könnte auch vorab mit printf die führende Null einfügen, falls nötig:
startzahl=$(printf "%03d" $startzahl)
for i in $(eval echo "{$startzahl .. $endzahl}")
|
KeyzerSoze
(Themenstarter)
Anmeldungsdatum: 28. September 2014
Beiträge: 120
|
seahawk1986 schrieb: Man könnte auch vorab mit printf die führende Null einfügen, falls nötig:
startzahl=$(printf "%03d" $startzahl)
Sehr elegant ☺ Das löst mein Problem!
Danke vielmals!
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Vielleicht noch 3 Anmerkungen:
Das eval ist hier überflüssig, und sogar gefährlich: denn man kann an dieser Stelle sonst was für Schadcode einschleusen, eine Untershell brauchst Du auch nicht: Du kannst die Datei-Umleitung direkt an die Schleife anhängen, und wildes "Quoting" ist ist auch nicht professionell, sondern einfach nur Quatsch. Im Grunde brauchst Du hier nix "quoten", denn Du hast ja fast nur Zahlen:
| n1=5
n2=11
for (( i=n1; i<=n2; i++ )); do
printf %3.3i.txt\\n $i
done > meinekonfigurationsdatei.in
|
(Ja, ein einziges Zeichen habe ich \escaped: sonst hätte er den Zeilenumbruch "\n" nicht verstanden.) LG, track
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17605
Wohnort: Berlin
|
For sowas brauchts kein for: | echo -e "\n"{099..101}".txt" | sed '1d' > meinekonfigurationsdatei.in
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13176
|
Warum so umständlich? Das geht doch viel einfacher so | printf '%03d.txt\n' {50..150} > meinekonfigurationsdatei.in
|
|
KeyzerSoze
(Themenstarter)
Anmeldungsdatum: 28. September 2014
Beiträge: 120
|
Okay, als Themensteller bin ich vollkommen gescheitert ☹ Mir tut es Leid, dass sich die Aufgabenstellung wieder ein wenig verändert. Ich dachte ich würde es mit Euren Hilfestellungen hinkriegen, aber dem ist leider nicht so ☹ Was ich als Ergebnis brauche, ist folgendes: 050name.txt
50
30 (ohne Null davor)
und
noch
viel konstanter Text (mit grep)
051name.txt
51
31 (ohne Null davor)
und
noch
viel konstanter Text (mit grep)
052name.txt
52
32 (ohne Null davor)
und
noch
viel konstanter Text (mit grep)
...
100name.txt
100
80 (ohne Null davor)
und
noch
viel konstanter Text (mit grep)
...
120.name.txt
120
100 (ohne Null davor)
und
noch
viel konstanter Text (mit grep)
Bemerkung1: 050 (der Laufindex) soll als Variable mittels read eingelesen werden.
}}}
Bemerkung2: die 3. Zahl, im Beispiel 30, soll eine konstante Verschiebung vom Laufindex sein. [ich hätte es mir so vorgestellt: $ (( i - 20 )) , aber das klappt nicht, weil wenn z.B. das "i" = 058 ist, dann zeigt er mir einen Fehler an] Ich hätte eben gedacht, dass für diese Aufgabe eine For-schleife praktisch ist, weil viel konstanter Text kopiert wird. Nochmal sorry, dass ich nicht gleich die ganze Aufgabenstellung hingeschrieben habe ☺
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Das Problem bei solchen Zahlen mit führender Null ist (in der Shell !), dass sie dann als oktal verstanden werden. (→ hier im letzten Abschnitt) Also: solche Zahlen grundsätzlich entweder ohne führende Null, oder ausdrücklich mit der Basisangabe 10 (→ "10#080"), oder gleich was anderes nehmen: track@track:~$ for i in {99..101}; do printf "%3.3iname.txt\n%i\n%i\nviel Text ...\n...\n" $i $i $((i-20)); done
099name.txt
99
79
viel Text ...
...
100name.txt
100
80
viel Text ...
...
101name.txt
101
81
viel Text ...
...
track@track:~$ for i in {099..101}; do echo -e "${i}name.txt\n$((10#$i+0))\n$((10#$i-20))\nviel Text ...\n..."; done
099name.txt
99
79
viel Text ...
...
100name.txt
100
80
viel Text ...
...
101name.txt
101
81
viel Text ...
...
track@track:~$ awk 'BEGIN {for(i=99; i<=101; i++) printf ("%3.3iname.txt\n%i\n%i\nviel Text ...\n...\n",i,i,i-20)}'
099name.txt
99
79
viel Text ...
...
100name.txt
100
80
viel Text ...
...
101name.txt
101
81
viel Text ...
...
LG, track
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13176
|
KeyzerSoze schrieb: Okay, als Themensteller bin ich vollkommen gescheitert ☹ Mir tut es Leid, dass sich die Aufgabenstellung wieder ein wenig verändert.
Ja, das ist nicht so hilfreich und führt meist zu Verwirrung.
Was ich als Ergebnis brauche, ist folgendes:
Was ist "Text (mit grep)"?
Bemerkung1: 050 (der Laufindex) soll als Variable mittels read eingelesen werden.
Von der Konsole (also einem Menschen) oder aus einer Datei? Und wozu? Vielleicht erklärst Du doch mal den gesamten Use Case.
Bemerkung2: die 3. Zahl, im Beispiel 30, soll eine konstante Verschiebung vom Laufindex sein. [ich hätte es mir so vorgestellt: $ (( i - 20 )) , aber das klappt nicht, weil wenn z.B. das "i" = 058 ist, dann zeigt er mir einen Fehler an]
Siehe tracks Erläuterungen zu Zahlensystemen. Ich denke, die führenden Nullen produziert man am besten erst bei der Ausgabe (z.B. mit printf ).
Ich hätte eben gedacht, dass für diese Aufgabe eine For-schleife praktisch ist, weil viel konstanter Text kopiert wird.
Wenn wir mal wüssten, was "diese Aufgabe" eigentlich ist...
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17605
Wohnort: Berlin
|
Bemerkung1: 050 (der Laufindex) soll als Variable mittels read eingelesen werden.
Dann scheidet {von..bis} (Shellinternal) leider aus und Du musst entweder zu einer for-loop greifen, oder mit seq arbeiten. | a=99; for i in $(seq $a $((a+3)))
do
printf "foo %3.3d.name bar\nfoobar $i $((i-20))\nipsum lore\n\n" $i
done
|
|
KeyzerSoze
(Themenstarter)
Anmeldungsdatum: 28. September 2014
Beiträge: 120
|
Vielen Dank Euch allen, es funktioniert wunderbar ☺ rklm schrieb: Was ist "Text (mit grep)"?
Ich wollte damit sagen, dass ich grep-Funktionen verwenden möchten. Mit den präsentierten Lösungen funkioniert das wunderbar ☺ Vielleicht erklärst Du doch mal den gesamten Use Case.
Wenn wir mal wüssten, was "diese Aufgabe" eigentlich ist...
Ich schreibe eine Konfigurationsdatei für ein Fortranprogramm, das ich mit einem weiteren Bashskript in einem Loop ausführe und dabei kontinuierlich bei jedem Loopschritt ein Stück Konfigurationsdatei automatisch einlesen lasse. track schrieb: Vielleicht noch 3 Anmerkungen:
Das eval ist hier überflüssig, und sogar gefährlich: denn man kann an dieser Stelle sonst was für Schadcode einschleusen, eine Untershell brauchst Du auch nicht: Du kannst die Datei-Umleitung direkt an die Schleife anhängen, und wildes "Quoting" ist ist auch nicht professionell, sondern einfach nur Quatsch.
Punkt 2 und 3 sehe ich sofort ein ☺ Punkt 1 ist mir noch nicht klar:
Nächstes Mal werde ich seq verwenden, wenn das sicherer ist ☺
n1=3
n2=5
for i in $(echo {$n1..$n2});do echo $i.txt; done
Liefert:
{3..5}.txt n1=3
n2=5
for i in $(eval echo {$n1..$n2});do echo $i.txt; done
Liefert:
3.txt
4.txt
5.txt n1=3
n2=5
for i in $(seq $n1 $n2); do echo $i.txt; done
Liefert:
3.txt
4.txt
5.txt
Kannst Du bitte beschreiben inwiefern ich eval weglassen kann, in meinem Minimalbeispiel funktioniert es nämlich nicht ☹ user_unknown schrieb: | a=99; for i in $(seq $a $((a+3)))
do
printf "foo %3.3d.name bar\nfoobar $i $((i-20))\nipsum lore\n\n" $i
done
|
Prinzipiell finde ich diese Lösung sehr schön, ich verstehe nur 2 Sachen nicht:
Wie weiß das Programm, dass das %3.3d der Laufindex ist. Was macht das (für mich) misteriöse $i außerhalb der printf-Umgebung?
Viele Grüße und besten Dank!
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Das gefährliche an eval ist, dass Du dort über die Variablen jedweden Schadcode einfügen kannst: track@track:~$ n1=9
track@track:~$ n2=11
track@track:~$ for i in $(eval echo "{$n1..$n2}") ; do echo $i; done
9
10
11
track@track:~$ n1="}; date; "
track@track:~$ for i in $(eval echo "{$n1..$n2}") ; do echo $i; done
..11}: Befehl nicht gefunden.
{}
Di
17.
Jan
22:09:08
CET
2017 Hier habe ich symbolisch mal nur den date - Befehl eingeschleust, und der wird ausgeführt. Aber das könnte ja durchaus was Bösartigeres sein ... 😉 Ein seq würde ich gar nicht mal nehmen: zu umständlich. Du kannst in der for - Schleife direkt Variablen einfügen, so wie ich es schon in meinem 1. Beitrag gezeigt habe. Bei der printf - Formatierung wird der Reihe nach für jeden Platzhalter die jeweilige Variablen dahinter eingesetzt. Lies es mal im prinf - Wiki nach ... LG, track
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17605
Wohnort: Berlin
|
KeyzerSoze schrieb: user_unknown schrieb: | a=99; for i in $(seq $a $((a+3)))
do
printf "foo %3.3d.name bar\nfoobar $i $((i-20))\nipsum lore\n\n" $i
done
|
Prinzipiell finde ich diese Lösung sehr schön, ich verstehe nur 2 Sachen nicht:
Wie weiß das Programm, dass das %3.3d der Laufindex ist.
Ist es nicht. Das ist ein Formatierungsstring für ein Argument, der später zugegeben wird.
Was macht das (für mich) misteriöse $i außerhalb der printf-Umgebung?
Das ist das Argument.
| printf "%4.4d Brötchen für %2.2d Esser\n" 916 916
0916 Brötchen für 916 Esser
|
Das kann eine literale Zahl sein, eine Variable, das Ergebnis einer Berechnung oder die Ausgabe eines Programms oder einer Funktion. Siehe auch help printf und man -a printf. Ich finde die Formatierungsstrings schwer durchschaubar und halte mich daher davon fern. Was "%4.4d" bedeutet weiß ich nicht wirklich. % leitet den String ein, d steht für digits, 4 irgendwie für 4 Stellen aber wieso 4.4?
|