Hallo, bisher bin ich immer davon ausgegangen das das Auftreten von {} alleine auf find beschränkt ist. Bsp.: find . -type f -exec file '{}' \; {} wird hier ersetzt durch den aktuell gefundenen Dateinamen. Hier bin ich bisher davon ausgegangen das '{}' eine Spezialität von find ist. Jetzt bin ich über folgendes gestolpert: awk -F"|" '$2 ~ 05478900172 {print $3}' input.log | sort -u | xargs -I {} grep {} input.log (https://unix.stackexchange.com/questions/189340/how-to-save-variables-in-a-s...) Und bin etwas verwirrt. Bei find sind die Klammern in einfachen Hochkommas, damit die Shell nichts damit macht. Im zweiten Beispiel fehlen die Hochkommas. D.h. die shell macht irgendwas damit. Was ? Bzw. wie interpretiert sie {} ? Ich wusste bisher nicht das {} irgendeine Bedeutung für die shell hat. In man xargs taucht dieses Beispiel auf: somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}' Hier ist {} jetzt wieder vor einer Interpretation durch die shell geschützt !?! Totale Verwirrung. Dankbar für erhellende Informationen. Bernd -- Bernd Lentes System Administrator Institute for Metabolism and Cell Death (MCD) Building 25 - office 122 HelmholtzZentrum München bernd.lentes@helmholtz-muenchen.de phone: +49 89 3187 1241 fax: +49 89 3187 2294 http://www.helmholtz-muenchen.de/mcd Public key: 30 82 01 0a 02 82 01 01 00 b3 72 3e ce 2c 0a 6f 58 49 2c 92 23 c7 b9 c1 ff 6c 3a 53 be f7 9e e9 24 b7 49 fa 3c e8 de 28 85 2c d3 ed f7 70 03 3f 4d 82 fc cc 96 4f 18 27 1f df 25 b3 13 00 db 4b 1d ec 7f 1b cf f9 cd e8 5b 1f 11 b3 a7 48 f8 c8 37 ed 41 ff 18 9f d7 83 51 a9 bd 86 c2 32 b3 d6 2d 77 ff 32 83 92 67 9e ae ae 9c 99 ce 42 27 6f bf d8 c2 a1 54 fd 2b 6b 12 65 0e 8a 79 56 be 53 89 70 51 02 6a eb 76 b8 92 25 2d 88 aa 57 08 42 ef 57 fb fe 00 71 8e 90 ef b2 e3 22 f3 34 4f 7b f1 c4 b1 7c 2f 1d 6f bd c8 a6 a1 1f 25 f3 e4 4b 6a 23 d3 d2 fa 27 ae 97 80 a3 f0 5a c4 50 4a 45 e3 45 4d 82 9f 8b 87 90 d0 f9 92 2d a7 d2 67 53 e6 ae 1e 72 3e e9 e0 c9 d3 1c 23 e0 75 78 4a 45 60 94 f8 e3 03 0b 09 85 08 d0 6c f3 ff ce fa 50 25 d9 da 81 7b 2a dc 9e 28 8b 83 04 b4 0a 9f 37 b8 ac 58 f1 38 43 0e 72 af 02 03 01 00 01
Hallo, Am 2021-12-14 21:08, schrieb Lentes, Bernd:
Hallo,
bisher bin ich immer davon ausgegangen das das Auftreten von {} alleine auf find beschränkt ist. Bsp.: find . -type f -exec file '{}' \; {} wird hier ersetzt durch den aktuell gefundenen Dateinamen. Hier bin ich bisher davon ausgegangen das '{}' eine Spezialität von find ist.
Meines Wissens nach spielen {} selbst keine Rolle für die bash, lediglich für das anhängige Programm. Ob Du sie in Hochkommata setzt oder nicht sollte am Ergebnis der Befehlskette nichts ändern lg
Jetzt bin ich über folgendes gestolpert: awk -F"|" '$2 ~ 05478900172 {print $3}' input.log | sort -u | xargs -I {} grep {} input.log (https://unix.stackexchange.com/questions/189340/how-to-save-variables-in-a-s...) Und bin etwas verwirrt. Bei find sind die Klammern in einfachen Hochkommas, damit die Shell nichts damit macht. Im zweiten Beispiel fehlen die Hochkommas. D.h. die shell macht irgendwas damit. Was ? Bzw. wie interpretiert sie {} ? Ich wusste bisher nicht das {} irgendeine Bedeutung für die shell hat. In man xargs taucht dieses Beispiel auf: somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}' Hier ist {} jetzt wieder vor einer Interpretation durch die shell geschützt !?! Totale Verwirrung. Dankbar für erhellende Informationen.
Bernd
--
Bernd Lentes System Administrator Institute for Metabolism and Cell Death (MCD) Building 25 - office 122 HelmholtzZentrum München bernd.lentes@helmholtz-muenchen.de phone: +49 89 3187 1241 fax: +49 89 3187 2294 http://www.helmholtz-muenchen.de/mcd
Public key:
30 82 01 0a 02 82 01 01 00 b3 72 3e ce 2c 0a 6f 58 49 2c 92 23 c7 b9 c1 ff 6c 3a 53 be f7 9e e9 24 b7 49 fa 3c e8 de 28 85 2c d3 ed f7 70 03 3f 4d 82 fc cc 96 4f 18 27 1f df 25 b3 13 00 db 4b 1d ec 7f 1b cf f9 cd e8 5b 1f 11 b3 a7 48 f8 c8 37 ed 41 ff 18 9f d7 83 51 a9 bd 86 c2 32 b3 d6 2d 77 ff 32 83 92 67 9e ae ae 9c 99 ce 42 27 6f bf d8 c2 a1 54 fd 2b 6b 12 65 0e 8a 79 56 be 53 89 70 51 02 6a eb 76 b8 92 25 2d 88 aa 57 08 42 ef 57 fb fe 00 71 8e 90 ef b2 e3 22 f3 34 4f 7b f1 c4 b1 7c 2f 1d 6f bd c8 a6 a1 1f 25 f3 e4 4b 6a 23 d3 d2 fa 27 ae 97 80 a3 f0 5a c4 50 4a 45 e3 45 4d 82 9f 8b 87 90 d0 f9 92 2d a7 d2 67 53 e6 ae 1e 72 3e e9 e0 c9 d3 1c 23 e0 75 78 4a 45 60 94 f8 e3 03 0b 09 85 08 d0 6c f3 ff ce fa 50 25 d9 da 81 7b 2a dc 9e 28 8b 83 04 b4 0a 9f 37 b8 ac 58 f1 38 43 0e 72 af 02 03 01 00 01
----- On Dec 15, 2021, at 10:18 AM, Markus Heinze max@freecards.de wrote:
Hallo,
Meines Wissens nach spielen {} selbst keine Rolle für die bash, lediglich für das anhängige Programm. Ob Du sie in Hochkommata setzt oder nicht sollte am Ergebnis der Befehlskette nichts ändern
Jetzt bin ich über folgendes gestolpert: awk -F"|" '$2 ~ 05478900172 {print $3}' input.log | sort -u | xargs -I {} grep {} input.log
Und was bedeutet hier die {} im Zusammenhang mit grep und xargs ? Bernd
Am 15.12.21 um 17:25 schrieb Lentes, Bernd:
----- On Dec 15, 2021, at 10:18 AM, Markus Heinze max@freecards.de wrote:
Hallo,
Meines Wissens nach spielen {} selbst keine Rolle für die bash, lediglich für das anhängige Programm. Ob Du sie in Hochkommata setzt oder nicht sollte am Ergebnis der Befehlskette nichts ändern
Jetzt bin ich über folgendes gestolpert: awk -F"|" '$2 ~ 05478900172 {print $3}' input.log | sort -u | xargs -I {} grep {} input.log
Und was bedeutet hier die {} im Zusammenhang mit grep und xargs ?
Hallo Bernd, führe einfach folgenden Befehl in der Shell aus, dann weiß du gleich, was es macht und kannst es daraus ableiten. # echo -n test1 test2 test3 | xargs -d" " -I {} echo "*{}*" Ansonsten wie immer die Empfehlung in den Manpages oder Infodocs auf der Shell zum Kommando "xargs" reinschauen. Dort wird es auch ausführlich erklärt. ;-) # man xargs # info xargs -- Gruß Sebastian - openSUSE Member (Freespacer) - Wichtiger Hinweis zur openSUSE Mailing Liste: https://de.opensuse.org/openSUSE:Mailinglisten_Netiquette
Am 15.12.21 um 17:53 schrieb Sebastian Siebert:
Am 15.12.21 um 17:25 schrieb Lentes, Bernd:
----- On Dec 15, 2021, at 10:18 AM, Markus Heinze max@freecards.de wrote:
Hallo,
Meines Wissens nach spielen {} selbst keine Rolle für die bash, lediglich für das anhängige Programm. Ob Du sie in Hochkommata setzt oder nicht sollte am Ergebnis der Befehlskette nichts ändern
Jetzt bin ich über folgendes gestolpert: awk -F"|" '$2 ~ 05478900172 {print $3}' input.log | sort -u | xargs -I {} grep {} input.log
Und was bedeutet hier die {} im Zusammenhang mit grep und xargs ?
Hallo Bernd,
führe einfach folgenden Befehl in der Shell aus, dann weiß du gleich, was es macht und kannst es daraus ableiten.
# echo -n test1 test2 test3 | xargs -d" " -I {} echo "*{}*"
Alternativ auch dieses Beispiel, was eher deiner Zeile entspricht: # echo -e "test1\ntest2\ntest3\n" | xargs -I {} echo "*{}*" -- Gruß Sebastian - openSUSE Member (Freespacer) - Wichtiger Hinweis zur openSUSE Mailing Liste: https://de.opensuse.org/openSUSE:Mailinglisten_Netiquette
Am Mittwoch, 15. Dezember 2021, 17:58:42 CET schrieb Sebastian Siebert: Hallo, Vielleicht versteh' ich's nicht richtig, aber der Effekt ist bei mir der gleiche:
# echo -n test1 test2 test3 | xargs -d" " -I {} echo "*{}*" *test1* *test2* *test3*
Alternativ auch dieses Beispiel, was eher deiner Zeile entspricht:
# echo -e "test1\ntest2\ntest3\n" | xargs -I {} echo "*{}*" *test1* *test2* *test3*
schönen Abend Frank
----- On Dec 15, 2021, at 5:53 PM, Sebastian Siebert freespacer@gmx.de wrote:
Am 15.12.21 um 17:25 schrieb Lentes, Bernd:
Hallo Bernd,
führe einfach folgenden Befehl in der Shell aus, dann weiß du gleich, was es macht und kannst es daraus ableiten.
# echo -n test1 test2 test3 | xargs -d" " -I {} echo "*{}*"
Jetzt hab ich's. Danke ! Was hinter I erscheint (hier: {}) wird im weiteren Verlauf der Kommandozeile durch das ersetzt was von stdin kommt. Es kann auch ein anderes Zeichen sein, z.B. %. Anscheinend haben sich die zwei Klammern als Quasistandard etabliert.
Ansonsten wie immer die Empfehlung in den Manpages oder Infodocs auf der Shell zum Kommando "xargs" reinschauen. Dort wird es auch ausführlich erklärt. ;-)
# man xargs Hatte ich reingeschaut, aber nicht verstanden.
-- Gruß Sebastian - openSUSE Member (Freespacer) - Wichtiger Hinweis zur openSUSE Mailing Liste: https://de.opensuse.org/openSUSE:Mailinglisten_Netiquette
15.12.21 um 18:37 schrieb eilf:
Am Mittwoch, 15. Dezember 2021, 17:58:42 CET schrieb Sebastian Siebert:
Hallo,
Vielleicht versteh' ich's nicht richtig, aber der Effekt ist bei mir der gleiche:
# echo -n test1 test2 test3 | xargs -d" " -I {} echo "*{}*" *test1* *test2* *test3*
Alternativ auch dieses Beispiel, was eher deiner Zeile entspricht:
# echo -e "test1\ntest2\ntest3\n" | xargs -I {} echo "*{}*" *test1* *test2* *test3*
Hallo Frank, das Ergebnis ist das gleiche, wie du bereits schon festgestellt hast. Es ging nur darum wie die Daten per stdout vom ersten echo-Kommando via pipe-Operator (|) per stdin an xargs an den zweiten echo-Kommando übergeben werden. Ersteres ist nur eine einzige Zeile mit Leerzeichen getrennt und zweiteres ist pro Zeile ein Ergebnis mit Zeilenumbrüchen getrennt (Standardfall für xargs). Hinten raus ist das Ergebnis wie gesagt identisch. Es gibt auch noch die Möglichkeit Zeichenkette mit dem Steuerzeichen NULL bzw. \0 (ASCII-Code ist tatsächlich 0) zu trennen und macht unter anderem dort Sinn, wenn man eine Liste von Dateinamen an xargs übergeben möchte, die auch Leerzeichen (vielleicht auch mit einem Zeilenumbruch, ja das geht, wenn auch unüblich) im Dateinamen beinhalten können. # echo -n -e "test1 mit leerzeilen\0test2\nmit\nzeilenumbrüchen\0test3\0" | xargs --null -I {} echo "*{}*" Hier mal eine kleine Demonstration, was man mit xargs alles anstellen kann. Beispiel: Wenn ich wissen will, welche Rechte und welchem Besitzer die Dateien mit der Endung .sh im Verzeichnis /usr/bin zugeordnet sind, dann kann ich diese einfach mit dem find-Kommando mit xargs + "ls -la" kombinieren: # find /usr/bin -iname "*.sh" -print0 | xargs --null -I {} ls -la "{}" Vielleicht wird das so für den einen oder anderen Shell-Interessierten verständlicher. -- Gruß Sebastian - openSUSE Member (Freespacer) - Wichtiger Hinweis zur openSUSE Mailing Liste: https://de.opensuse.org/openSUSE:Mailinglisten_Netiquette
Hallo, Am Donnerstag, 16. Dezember 2021 16:08 schrieb Sebastian Siebert:
Es gibt auch noch die Möglichkeit Zeichenkette mit dem Steuerzeichen NULL bzw. \0 (ASCII-Code ist tatsächlich 0) zu trennen und macht unter anderem dort Sinn, wenn man eine Liste von Dateinamen an xargs übergeben möchte, die auch Leerzeichen (vielleicht auch mit einem Zeilenumbruch, ja das geht, wenn auch unüblich) im Dateinamen beinhalten können.
# echo -n -e "test1 mit leerzeilen\0test2\nmit\nzeilenumbrüchen\0test3\0" | xargs --null -I {} echo "*{}*"
fswatch kann auf Wunsch seine Ausgabe so formatieren. -- Gruß Marcus
Hallo, Am Wed, 15 Dec 2021, Markus Heinze schrieb:
Am 2021-12-14 21:08, schrieb Lentes, Bernd:
bisher bin ich immer davon ausgegangen das das Auftreten von {} alleine auf find beschr=E4nkt ist. Bsp.: find . -type f -exec file '{}' \; {} wird hier ersetzt durch den aktuell gefundenen Dateinamen. Hier bin ich bisher davon ausgegangen das '{}' eine Spezialit=E4t von find ist.
Meines Wissens nach spielen {} selbst keine Rolle f=FCr die bash,
Doch! ==== man bash ==== { list; } list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. ==== Das braucht man z.B. um Ausgaben mehrerer Kommandos zusammenzufassen: $ echo "foo"; echo "bar" | wc foo 1 1 4 $ { echo "foo"; echo "bar"; } | wc 2 2 8
lediglich für das anhängige Programm. Ob Du sie in Hochkommata setzt oder nicht sollte am Ergebnis der Befehlskette nichts ändern
Man muß die '{}' quoten _falls_ sie sonst anders erkannt werden.
Jetzt bin ich über folgendes gestolpert: awk -F"|" '$2 ~ 05478900172 {print $3}' input.log | sort -u | xargs -I {} grep {} input.log (https://unix.stackexchange.com/questions/189340/how-to-save-variables-in-a-s...) Und bin etwas verwirrt. Bei find sind die Klammern in einfachen Hochkommas, damit die Shell nichts damit macht.
Korrekt. Und in awk (und anderen Sprachen wie C, perl, TeX ...) gibt's die {} ja auch ;)
Im zweiten Beispiel fehlen die Hochkommas. D.h. die shell macht irgendwas damit. Was ? Bzw. wie interpretiert sie {} ?
In diesem Sonderfall gar nicht. Bei sowas helfen übrigens zuverlässig 'set -x' und 'set -v' $ set -x; set -v $ foo=bar; foo=bar; # -v, was gelesen wird % :14: foo=bar # -x, was ausgeführt wird $ echo "$foo" | xargs -I {} grep {} /dev/null echo "$foo" | xargs -I {} grep {} /dev/null # -v, was gelesen wird % :14: echo bar # -x, was ausgeführt wird % :14: xargs -I '{}' grep '{}' /dev/null # -x, was ausgeführt wird $ set +x; set +v
Ich wusste bisher nicht das {} irgendeine Bedeutung für die shell hat.
RTFM. s.o.
In man xargs taucht dieses Beispiel auf: somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}' Hier ist {} jetzt wieder vor einer Interpretation durch die shell geschützt !?!
Ja, sollte man immer machen, auch wenn man nicht muß, denn das vermeidet ...
Totale Verwirrung.
... eben sowas ;) Es gibt eben die {} bei find und bei xargs gibt man einen Platzhalter per '-I'-Option an ... HTH, -dnh -- printk(KERN_CRIT PFX "Reboot didn't ?????\n"); linux-2.6.6/drivers/char/watchdog/softdog.c
Am Freitag, den 17.12.2021, 03:37 +0100 schrieb David Haller:
Hallo,
Am Wed, 15 Dec 2021, Markus Heinze schrieb:
Am 2021-12-14 21:08, schrieb Lentes, Bernd:
bisher bin ich immer davon ausgegangen das das Auftreten von {} alleine auf find beschr=E4nkt ist. Bsp.: find . -type f -exec file '{}' \; {} wird hier ersetzt durch den aktuell gefundenen Dateinamen. Hier bin ich bisher davon ausgegangen das '{}' eine Spezialit=E4t von find ist.
Meines Wissens nach spielen {} selbst keine Rolle f=FCr die bash,
Doch!
Doch nicht ;-))) In der Bash gibt eine Reihe von Konstrukten, die widersprüchlich erscheinen und noch mehr verwirren. 1. {} Wenn die Bash {} als Wort bekommt, ist es unbekannt und wird wie eine Folge von Zeichen behandelt. In unserem Fall wird es als Parameter übergeben. Bei '{}' und "{}" werden die Quotierungszeichen einfach entfernt. --> {} hat für die Bash keine Bedeutung: ls {} ls: Zugriff auf '{}' nicht möglich: Datei oder Verzeichnis nicht gefunden Hier mault ls und nicht die Bash. Es geht sogar :-) touch {}; ls -l {}; rm {} 2. {String,String} {a..e} {A..T..3} Hier handelt es sich um Brace-Expansion. Wir kennen es von ls Verzeichnis/{alt,mittel,neu}*.png Die Bash macht daraus Verzeichnis/alt*.png Verzeichnis/mittel*.png Verzeichnis/neu*.png und versucht dann die * zu ersetzen Im Beispiel: for f in /etc/{g*,hos?.,mich*nicht?}conf; do echo $f; done fummelt die Bash bei den * und ? herum. Mal echo durch ls ersetzen. Aus echo {A..T..3} wird A D G J M P S Wichtig ist dass in den {} keine Whitespaces wie Leerzeichen, Zeilenumbrüche oder TAbs stehen. echo {a .. e} bringt nicht den gewünschten Effekt, aber echo A_{a..e}"_Z " 3. { Befehl; NochEiner; } Hier handelt es sich um einen zusammengesetzten Befehl ähnlich (ls; echo; la -r) aber eben doch anders. (ls; echo; la -r) läuft in einer Subshell ab. { Befehl; NochEiner; } im läuft Kontext der aktuellen Shell. Syntaktisch unterscheiden sich beide: Hinter ( und vor ) sind keine Whitespaces erforderlich. Das letzte Semikolon vor ) kann entfallen. Hinter { ist ein Whitespace erforderlich. Vor } ist ein Semikolon erforderlich. Ein Semikolon kann durch einen Zeilenumbruch ersetzt werden. Eigentlich entspricht { Befehl; NochEiner; } einfach Befehl; NochEiner; In Funktionen werden { .. } verwendet, aber auch z.B. in { echo "PASSWD follows"; cat /etc/passwd echo; echo "GROUPS follows"; cat /etc/group } >output.txt Noch doller ist :-))) { touch {}; ls -l {}; rm {}; } 4. ${usw} Hier geht es um ${ Das sind Parameter- und Variablenexpansionen von denen es auch noch eine Reihe von Varianten einschließlich Mustererkennung und -ersetzung gibt. Damit kann man sich z.B. sed-Klimmzüge ersparen: echo ${HOME/home/Heimat} echo Ein Spass, den nur die Bash versteht: ${HOME////:-)} Mehr in https://www.gnu.org/software/bash/manual/bash.html#Shell-Expansions :-)) ff -- viel Vergügen Vielleicht hift's Grüße Heiner
==== man bash ==== { list; } list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. ====
Das braucht man z.B. um Ausgaben mehrerer Kommandos zusammenzufassen:
$ echo "foo"; echo "bar" | wc foo 1 1 4 $ { echo "foo"; echo "bar"; } | wc 2 2 8
lediglich für das anhängige Programm. Ob Du sie in Hochkommata setzt oder nicht sollte am Ergebnis der Befehlskette nichts ändern
Man muß die '{}' quoten _falls_ sie sonst anders erkannt werden.
Jetzt bin ich über folgendes gestolpert: awk -F"|" '$2 ~ 05478900172 {print $3}' input.log | sort -u | xargs -I {} grep {} input.log ( https://unix.stackexchange.com/questions/189340/how-to-save-variables-in-a-s... ) Und bin etwas verwirrt. Bei find sind die Klammern in einfachen Hochkommas, damit die Shell nichts damit macht.
Korrekt. Und in awk (und anderen Sprachen wie C, perl, TeX ...) gibt's die {} ja auch ;)
Im zweiten Beispiel fehlen die Hochkommas. D.h. die shell macht irgendwas damit. Was ? Bzw. wie interpretiert sie {} ?
In diesem Sonderfall gar nicht. Bei sowas helfen übrigens zuverlässig 'set -x' und 'set -v'
$ set -x; set -v $ foo=bar; foo=bar; # -v, was gelesen wird % :14: foo=bar # -x, was ausgeführt wird $ echo "$foo" | xargs -I {} grep {} /dev/null echo "$foo" | xargs -I {} grep {} /dev/null # -v, was gelesen wird % :14: echo bar # -x, was ausgeführt wird % :14: xargs -I '{}' grep '{}' /dev/null # -x, was ausgeführt wird $ set +x; set +v
Ich wusste bisher nicht das {} irgendeine Bedeutung für die shell hat.
RTFM. s.o.
In man xargs taucht dieses Beispiel auf: somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}' Hier ist {} jetzt wieder vor einer Interpretation durch die shell geschützt !?!
Ja, sollte man immer machen, auch wenn man nicht muß, denn das vermeidet ...
Totale Verwirrung.
... eben sowas ;)
Es gibt eben die {} bei find und bei xargs gibt man einen Platzhalter per '-I'-Option an ...
HTH, -dnh
participants (7)
-
David Haller
-
eilf
-
Heiner Kuhlmann
-
Lentes, Bernd
-
Marcus Roeckrath
-
Markus Heinze
-
Sebastian Siebert