Puncte:7

BASH: Cum pot combina două (sau mai multe) manipulări de șiruri variabile într-un singur pas?

drapel tr

Este posibil să combinați două sau mai multe funcționalități de manipulare a șirurilor de caractere ale unei variabile în BASH (sau orice altă comandă standard Linux)?

Sa spunem de exemplu. Am variabila $XDG_CURRENT_DESKTOP care ține sfoara ubuntu:GNOME.
Acum, pot prelua al doilea subșir prin ${XDG_CURRENT_DESKTOP##*:} â GNOME.
De asemenea, pot prelua șirul minuscule ${XDG_CURRENT_DESKTOP,,} â ubuntu:gnome.

Dar cum pot combina ambele funcții gnom) în unu â simplu â comandă fără a utiliza o redirecționare către sed, awk, grep sau oricare dintre acestea â destul de greu ponderat â comenzi și fără un pas suplimentar de stocare tampon? de exemplu.:

local mybuffer="${XDG_CURRENT_DESKTOP##*:}"
echo „${mybuffer,,}”

Vreau să evit un astfel de „subscript” sau o construcție de apel de funcție pentru a realiza acest lucru și am încercat deja orice combinație a ambelor menționate, dar pare a fi inutil.
Există vreo altă cale?
Sau trebuie să fac upgrade bash? (folosind: GNU bash 4.3.11)
Sau poate orice alt shell să facă asta?

drapel hr
`zsh` o poate face, cu indicatorul de extindere a parametrului `L`, de ex. `${(L)XDG_CURRENT_DESKTOP##*:}`
Jens avatar
drapel tr
@steeldriver: Oohhh, frumos! _ACĂ_ este exact ceea ce căutam! E timpul pentru `zsh`. Mulțumesc foarte mult! :))
terdon avatar
drapel cn
@steeldriver ar putea la fel de bine să posteze asta ca răspuns, deoarece OP a cerut și alte shell-uri.
Jens avatar
drapel tr
@terdon: de acord
Puncte:4
drapel cn

Ai putea face asta în bash daca folosesti citit pentru a citi două variabile:

$ echo „$XDG_CURRENT_DESKTOP”
ubuntu:GNOME
$ IFS=':' citește var1 var2 <<<"${XDG_CURRENT_DESKTOP@L}"
$ echo „$var2”
gnom

The ${variable@L} construct returnează valoarea lui $variabil convertit în litere mici. Atunci, IFS=':' citit setează separatorul câmpului de intrare la : pentru citit comandă, în acest fel IFS global este lăsat neschimbat după ieșirea comenzii și apoi citiți var1 var2 își va separa intrarea : și salvați rezultatul în cele două variabile var1 și var2. Rețineți că dacă aveți mai multe : pe aceeași linie în intrare, var1 va avea totul până la prima : și var2 orice altceva. In cele din urma, <<< este un „șir aici”, o modalitate simplă de a trece o variabilă ca intrare la o comandă.

Jens avatar
drapel tr
Frumoasă soluție! Dar, din păcate, această construcție este mult prea lungă și probabil cu multe procese de fundal _(â principiul KISS)_. BTW, cu această versiune bash cred că pot adopta combinația similară cu propunerea zsh de la @steeldriver de mai sus. Oricum, 1+ pentru inspirație!
terdon avatar
drapel cn
@Jens este lung și greu de scris, absolut. Zsh tinde să fie mai elegant cu astfel de lucruri. Dar multe procese de fundal? De ce? Acestea sunt toate instrumentele încorporate 100% bash, nu cred că va fi mult (nici?) implicat.
Jens avatar
drapel tr
Buna observatie! Încerc doar să implementez ceva de genul _"directiv/constant uniform"_ care chiar nu ar trebui să ia prea multă codare _și_ procesare în fundal.Între timp, am ajuns oricum la punctul că `zsh` ar putea fi contraproductiv datorită faptului că pare să nu fie distribuit pe scară largă. Deci nu prea are sens.
terdon avatar
drapel cn
@Jens zsh devine din ce în ce mai popular și este shell-ul implicit pe unele sisteme non-Ubuntu (macOS din câte știu, dar poate altele), dar da, nu puteți presupune că va fi disponibil. Dar atunci nici nu poți presupune că bash este disponibil :). Pentru o portabilitate adevărată, trebuie să rămâneți la un shell POSIX de bază, cum ar fi `sh` sau `dash`. Răspunsul meu depinde de bashisme, modalitatea portabilă ar fi să te conduci la un instrument extern portabil precum `sed` sau `perl`. Totuși, toate acestea sunt în afara subiectului aici, ne ocupăm doar de Ubuntu. Poate doriți să verificați [linux.se] pentru întrebări despre portabilitate.
Jens avatar
drapel tr
sh, dash, bash, zsh, etc. ⦠prea multe opțiuni ⦠Cred că am pierdut urma viziunii globale cu acest detaliu ;oP Trebuie să recunosc, nu am luat în considerare această problemă de shell încă. Poate că deocamdată ar trebui să rămân cu `bash`. Din această perspectivă, codul tău arată mult mai bine cu cât mă gândesc mai mult la el xD
Puncte:0
drapel ng

Iată un script bash5 (nu bash4):

partea 2() {
   local -n var=$1
   var=${var#*:}
}
lc() {
   local -n var=$1
   var=${var,,}
}
fred="ubuntu:gnome"
partea 2 fred
lc fred
printf "%s\n" "$fred"

Ieșire:

gnom

Funcțiile partea 2 și lc modificați variabila al cărei nume le este transmis, fără bifurcare. În cele din urmă, variabila inițială (fred) a fost modificat. Totuși, aveți nevoie de variabila suplimentară.

Alternativa, care ar trebui să funcționeze pe bash4, este cam așa:

part2() { printf "%s" "${1#*:}"; }
lc() { printf "%s" "${1,,}" ; }
fred="ubuntu:GNOME"
printf "%s\n" "$(lc "$(part2 "$fred")")"

care nu modifică nicio variabilă (se manipulează doar valori), dar creează furcături suplimentare.

Jens avatar
drapel tr
În primul rând: mulțumesc pentru efort. Rezultatul este ok. FYI: _tot_ codul tău este Bash4 în fapt ;-).Apreciez foarte mult programarea modulară, dar în acest caz căutam mai mult un cod de comandă unic sau, alternativ, un singur cod. Scuze, dar oricum multumesc mult.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.