rimuovi caratteri particolari da una variabile usando bash


123

Voglio analizzare una variabile (nel mio caso è la versione del kit di sviluppo) per renderla dot ( .) libera. Se version='2.3.3', l'output desiderato è 233.

Ho provato come di seguito, ma richiede .di essere sostituito con un altro personaggio che mi dà 2_3_3. Sarebbe andato bene se tr . ''avrebbe funzionato.

  1 VERSION='2.3.3' 
  2 echo "2.3.3" | tr . _

10
No, non richiede: echo "2.3.3" | tr -d ..
arte

1
@manatwork Fantastico, funziona. Puoi pubblicarlo come risposta. Grazie
prayagupd,

1
Molte buone risposte. Ma se riesco a indovinare di nuovo l'obiettivo, ti avverto di 2.11.3 e 2.1.13 ... ;-) Considera di aggiungere zeri di riempimento ai numeri.
Rmano,

1
@Rmano Intendi qualcosa del genere VERSION='2.30.3100'? Indipendentemente da ciò che .viene rimosso, con tutte le risposte qui.
Prayagupd,

2
@PrayagUpd --- Volevo semplicemente dire che se utilizzerai il numero dopo la conversione per i confronti (come dire se "questa versione è più recente o uguale") dovresti occuparti di casi come 2.11.3 e 2.1.13 - - sembrano uguali dopo la rimozione dei punti, ma chiaramente 2.11.3 è più recente. Inoltre, 2.11.3 è più recente di 2.1.14, ma il confronto tra 2113 e 2114 porterà a una risposta errata. Ricordo un bug da qualche parte per questo ...
Rmano,

Risposte:


136

Non è necessario eseguire un programma esterno. bashLa manipolazione di stringhe può gestirla (disponibile anche in ksh(da dove proviene) e zsh):

$ VERSION='2.3.3'
$ echo "${VERSION//.}"
233

(Nei manuali di quelle shell potete trovare questo nella sezione di espansione dei parametri.)


19
Per ulteriori dettagli, la sintassi della risposta sopra è ${string//substring/replacement}, dove apparentemente la mancanza della barra finale e della stringa di sostituzione finali viene interpretata come eliminazione . Vedi qui .
Sherrellbc,

5
Esatto, lo man bashdice chiaramente nella sezione Espansione parametri shell : “ ${parameter/pattern/string}(…) Se la stringa è nulla, le corrispondenze del modello vengono eliminate e il /seguente modello può essere omesso.”
manatwork

1
Il mio problema era che il numero di versione arrivava in questo modo "1.0.0"e volevo solo il numero, quindi segui quello che @manatwork mi ha suggerito di cambiare: "${VERSIONNUM//'"'}"tuttavia inserisco anche ' ' perché altrimenti non riconoscerebbe la ""stringa simile da decollare.
Alexiscanny,

1
@Alexiscanny, intendi letteralmente "presente nel valore? Temo che ciò valga come una nuova domanda, ma prova a sfuggire alla "${VERSIONNUM//\"}"
doppia citazione

1
Stupenda !! funziona -ashanche su !
Fr0zenFyr

88

Per ordine cronologico:

TR / sed

echo "$VERSION" | tr -d .
echo "$VERSION" | sed 's/\.//g'

csh / tcsh

echo $VERSION:as/.//

Shell POSIX:

set -f
IFS=.
set -- $VERSION
IFS=
echo "$*"

ksh / zsh / bash / yash (e busybox ashse costruito con ASH_BASH_COMPAT)

echo "${VERSION//.}"

zsh

echo $VERSION:gs/./

1
tr -d ha eliminato anche un singolo carattere dal set. Per Ex voglio eliminare DCC_ da "DCC_VersionD", Elimina DCC e D. Output previsto: VersionD. Uscita effettiva: versione. sed ha funzionato come un fascino. :) Grazie per il post.
kayle,

20

Oltre alle risposte positive esiste già. La stessa cosa si può ottenere trcon l' --deleteopzione.

echo "2.3.3" | tr --delete .

Che produrrà: 233


6
su macos la --deletebandiera non è riconosciuta, ma puoi usare -dinvece
Anentropic

6

dovresti provare sedinvece

sed 's/\.//g'


4
echo "$VERSION" | tr -cd [:digit:]

Ciò restituirebbe solo cifre, indipendentemente da quali altri personaggi siano presenti


4

Perl

$ VERSION='2.3.3'                                     
$ perl -pe 's/\.//g' <<< "$VERSION"           
233

Pitone

$ VERSION='2.3.3'                                     
$ python -c 'import sys;print sys.argv[1].replace(".","")' "$VERSION"
233

Se $VERSIONcontiene solo cifre e punti, possiamo fare qualcosa di ancora più breve:

$ python -c 'print "'$VERSION'".replace(".","")'
233

(attenzione è una vulnerabilità di iniezione di codice anche se $VERSIONpuò contenere qualsiasi carattere).

AWK

$ VERSION='2.3.3'
$ awk 'BEGIN{gsub(/\./,"",ARGV[1]);print ARGV[1]}' "$VERSION"
233

O questo:

$ awk '{gsub(/\./,"")}1' <<< "$VERSION"
233
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.