Eu li algumas outras perguntas sobre manipulação de string de bash de tubulação, mas elas parecem ser aplicativos especializados.
Essencialmente, existe uma maneira de fazer o abaixo mais simples?
ao invés de
$ string='hello world'; string2="${string// /_}"; echo "${string2^^}"
HELLO_WORLD
algo como
$ echo 'hello world' | $"{-// /_}" | "${ -^^}"
HELLO_WORLD
Editar Estou interessado em permanecer dentro de manipulações do bash, se possível, para manter a velocidade (em vez de sed / awk, que tendem a desacelerar bastante meus scripts)
Edit2: @jimmij
Eu gosto do segundo exemplo e me levou a fazer uma função.
bash_m() { { read x; echo "${x// /_}"; } | { read x; echo "${x^^}"; }; }
echo hello world | bash_m
HELLO_WORLD
bash
string
variable-substitution
Miati
fonte
fonte
tr
manual, o oposto será verdadeiro porque o tempo de geração dos processos é insignificante em comparação com o tempo de manipulação de cadeias para o qualsed
eawk
são dedicados. Se a string é extremamente longa, digamos o manual completo do bash, o bash pode se recusar a prosseguir completamente, devido a algumas limitações internas.sed
,awk
,tr
ou semelhantes. Veja a resposta do gena2x, que eu editei há algum tempo, adicionando exatamente essas informações: unix.stackexchange.com/questions/162221/… você pode compará-lo com terdon answer para a mesma pergunta em que ele dá tempo para seqüências curtas nas quais a geração do processo do caso leva mais tempo. Você pode testá-lo e postar o resultado.read x; echo $x
é melhor para o desempenho? A sintaxe não parece mais curta ou mais limpa.x=${x// /_}; x=${x^^}
é uma maneira muito mais concisa de fazer a mesma coisa que{read x; echo ${x...
. Quanto ao desempenho, o @jimmij apontou quetr
/sed
seria mais rápido do que abash
contagem de garfos sendo igual. O uso de um pipe sempre resulta em um processo extra, portanto o argumento de salvar um garfo não se aplica mais. Portanto, se você estiver usando pipes, usesed
/tr
etc. Se você puder fazê-lo no bash, faça-o e pule essaread x; echo $x
bobagem.Respostas:
O que jimmij disse. Seu último exemplo é o mais próximo que você pode chegar do que está tentando na sua expressão.
Aqui está uma variante desse tema:
Eu estaria inclinado a usar
tr
, pois é bastante rápido.Suponho que seja uma pena que o bash não permita a expansão de parâmetros aninhados; OTOH, o uso de tais expressões aninhadas pode facilmente levar a códigos difíceis de ler. A menos que você realmente precise que as coisas sejam executadas o mais rápido possível, é melhor escrever um código fácil de ler, entender e manter, em vez de um código de aparência inteligente que seja uma PITA para depuração. E se você realmente fazer precisa de coisas a ser feito em alta velocidade você deve estar usando código compilado, não um script.
fonte
Você não pode passar expansões de parâmetro dessa maneira. Quando você se refere ao
x
uso do$
símbolo como na"${x}"
forma, ele deve ser o nome da variável real, não uma entrada padrão, pelo menos nãobash
. Emzsh
você pode executar substituições de parâmetros aninhadas da seguinte maneira:(nota:
:u
é parazsh
o mesmo que^^
parabash
)O aninhamento no bash não é possível e acho que o que você escreveu em questão é o melhor possível, mas se por algum motivo estranho você precisar envolver tubos na equação, poderá tentar o seguinte:
fonte
tr
/sed
são mais rápidos do quebash
no processamento de strings e considerando como você está usando pipes para passar strings via E / S padrão, vejo literalmente ponto zero para realizar essas operações no bash em oposição atr
/sed
. Por que alguém| { read x; echo $x... }
em oposição a alguém| sed
que faz a mesma coisa?echo
eread
são embutidos no bash, portanto, em princípio, um pouco mais rápido). Como eu já escrevi na resposta, manipulações progressivas de parâmetros que o OP tem na pergunta é a melhor que posso obter na minha opinião para esta tarefa no bash. De qualquer forma, o problema é bastante acadêmico.