Se, por acaso, você estiver apenas tentando manipular cotações para reutilizar o shell, poderá fazer isso sem removê-las, e também é simples:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Essa função shell cita qualquer matriz arg que você a entrega e incrementa sua saída por argumento iterável.
Aqui está com alguns argumentos:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
RESULTADO
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
Essa saída é da dash
qual tipicamente aspas seguras saem entre aspas '"'"'
. bash
faria '\''
.
Substituir uma seleção de bytes únicos, sem espaço em branco e não nulos por outro byte único provavelmente pode ser feito mais rapidamente em qualquer shell POSIX com $IFS
e $*
.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
RESULTADO
"some ""crazy """"""""string ""here
Aí eu apenas printf
para que você possa ver, mas é claro, se eu tivesse feito:
var="$*"
... ao invés do valor do printf
comando $var
, seria o que você vê na saída.
Quando set -f
instruo o shell a não glob - caso a string contenha caracteres que possam ser interpretados como padrões glob. Eu faço isso porque o analisador de shells expande os padrões glob depois de executar a divisão de campo nas variáveis. globbing pode ser reativado como set +f
. Em geral - em scripts - acho útil definir meu estilo como:
#!/usr/bin/sh -f
E, em seguida, para ativar explicitamente englobamento com set +f
em qualquer linha que eu poderia desejar.
A divisão do campo ocorre com base nos caracteres em $IFS
.
Existem dois tipos de $IFS
valores - $IFS
espaço em branco e $IFS
não-espaço em branco. $IFS
os campos delimitados por espaço em branco (espaço, tabulação, nova linha) são especificados para eleger, por sequência, um único campo (ou nenhum, se não precederem outra coisa) - então ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Mas todos os outros são especificados para avaliar um único campo por ocorrência - eles não são truncados.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Todas as expansões variáveis são, por padrão, $IFS
matrizes de dados delimitadas - elas são divididas em campos separados de acordo com $IFS
. Ao "
citar uma, você substitui a propriedade da matriz e a avalia como uma única sequência.
Então, quando eu faço ...
IFS=\"\'\`; set -- $var
Estou definindo a matriz de argumentos do shell para os muitos $IFS
campos delimitados gerados pela $var
expansão do. Quando é expandido, seus valores constituintes para os caracteres contidos $IFS
são perdidos - eles são apenas separadores de campo agora - eles são \0NUL
.
"$*"
- como outras expansões variáveis de aspas duplas - também substitui as qualidades de divisão de campos de $IFS
. Mas, além disso , ele substitui o primeiro byte no $IFS
para cada campo delimitado em "$@"
. Então, porque "
foi o primeiro valor em $IFS
todos os delimitadores subseqüentes "
em que se tornou "$*"
. E a "
necessidade também não está presente $IFS
quando você a divide. Você poderia alterar $IFS
depois set -- $args
para outro valor completamente e seu novo primeiro byte apareceria para os delimitadores de campo em "$*"
. Além disso, você pode remover todos os traços deles como:
set -- $var; IFS=; printf %s "$*"
RESULTADO
some crazy string here
tr
. O PE do BASH é bom, mas tr é muito mais rápido nesse caso. por exemplo,echo "$OUTPUT" | tr -dc '[[:alpha:]]'
desde que você quer ter alphanumerics única