Se, per caso, stai solo cercando di gestire le virgolette per riutilizzare la shell, puoi farlo senza rimuoverle, ed è anche semplicissimo:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Quella shell di funzioni cita qualsiasi array arg che viene passato e ne incrementa l'output per argomento iterabile.
Eccolo con alcuni argomenti:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
PRODUZIONE
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
Quell'output proviene dash
da quello tipicamente sicuro quotazioni a virgoletta singola come '"'"'
. bash
farebbe '\''
.
La sostituzione di una selezione di byte singoli, non bianchi, non nulli con un altro singolo byte può essere probabilmente eseguita più rapidamente in qualsiasi shell POSIX con $IFS
e $*
.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
PRODUZIONE
"some ""crazy """"""""string ""here
Eccolo printf
lì, così puoi vederlo, ma ovviamente se avessi fatto:
var="$*"
... piuttosto che il valore del printf
comando $var
sarebbe quello che vedi nell'output lì.
Quando set -f
istruisco la shell di non glob, nel caso in cui la stringa contenga caratteri che potrebbero essere interpretati come modelli glob. Lo faccio perché il parser di shell espande i modelli glob dopo aver eseguito la divisione dei campi sulle variabili. il globbing può essere riattivato come set +f
. In generale, negli script, trovo utile impostare il mio botto come:
#!/usr/bin/sh -f
E poi per abilitare esplicitamente globbing con set +f
su qualsiasi linea che potrebbe desiderare.
La suddivisione dei campi avviene in base ai caratteri in $IFS
.
Esistono due tipi di $IFS
valori: $IFS
spazi bianchi e $IFS
non bianchi. $IFS
i campi delimitati da spazi bianchi (spazio, tabulazione, nuova riga) vengono specificati per elidare in sequenza in un singolo campo (o nessuno se non precedono qualcos'altro) - quindi ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Ma tutti gli altri sono specificati per valutare un singolo campo per occorrenza - non sono troncati.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Tutte le espansioni variabili sono, per impostazione predefinita, $IFS
array di dati delimitati - suddivisi in campi separati in base a $IFS
. Quando ne "
citate una, sovrascrivete quella proprietà dell'array e la valutate come una singola stringa.
Quindi quando lo faccio ...
IFS=\"\'\`; set -- $var
Sto impostando l'array di argomenti della shell sui molti $IFS
campi delimitati generati $var
dall'espansione di. Quando viene espanso, i suoi valori costitutivi per i caratteri contenuti $IFS
vengono persi - ora sono solo separatori di campo - lo sono \0NUL
.
"$*"
- come altre espansioni variabili tra virgolette doppie - sostituisce anche le qualità di divisione del campo di $IFS
. Ma, in aggiunta , esso sostituisce il primo byte $IFS
per ogni campo delimitato in "$@"
. Quindi perché è "
stato il primo valore in $IFS
tutti i delimitatori successivi "
in "$*"
. E "
non è nemmeno necessario che $IFS
tu lo divida. Si potrebbe modificare $IFS
dopo set -- $args
un altro valore del tutto e il suo nuovo primo byte potrebbe quindi presentarsi per i delimitatori di campo in "$*"
. Inoltre, è possibile rimuovere tutte le tracce del tutto come:
set -- $var; IFS=; printf %s "$*"
PRODUZIONE
some crazy string here
tr
. Il PE di BASH è buono, ma in questo caso tr è molto più veloce. ad es.echo "$OUTPUT" | tr -dc '[[:alpha:]]'
dal momento che si desidera avere solo caratteri alfanumerici