bash – forma más corta de reemplazar caracteres en una variable

Pregunta:

Hay muchas formas de reemplazar caracteres en una variable.

La forma más corta que descubrí es tr hasta ahora:

OUTPUT=a\'b\"c\`d_123and_a_lot_more
OUTPUT=$(echo "$OUTPUT"|tr -d "'\`\"")
echo $OUTPUT

¿Hay una manera mas rápida? ¿Y esta cita es segura para citas como ' , " y` en sí misma?

Respuesta:

Veamos. Lo más corto que se me ocurre es un ajuste de su solución tr :

OUTPUT="$(tr -d "\"\`'" <<<$OUTPUT)"

Otras alternativas incluyen la sustitución de variables ya mencionada que puede ser más corta que la mostrada hasta ahora:

OUTPUT="${OUTPUT//[\'\"\`]}"

Y sed por supuesto, aunque esto es más largo en términos de caracteres:

OUTPUT="$(sed s/[\'\"\`]//g <<<$OUTPUT)"

No estoy seguro de si te refieres a la menor duración o en términos de tiempo. En términos de longitud, estos dos son tan cortos como es posible (o como puedo obtenerlo de todos modos) cuando se trata de eliminar esos caracteres específicos. Entonces, ¿cuál es el más rápido? Probé estableciendo la variable OUTPUT en lo que tenía en su ejemplo, pero repetí varias docenas de veces:

$ echo ${#OUTPUT} 
4900

$ time tr -d "\"\`'" <<<$OUTPUT
real    0m0.002s
user    0m0.004s
sys     0m0.000s
$ time sed s/[\'\"\`]//g <<<$OUTPUT
real    0m0.005s
user    0m0.000s
sys     0m0.000s
$ time echo ${OUTPUT//[\'\"\`]}
real    0m0.027s
user    0m0.028s
sys     0m0.000s

Como puede ver, el tr es claramente el más rápido, seguido de cerca por sed . Además, parece que usar echo es en realidad un poco más rápido que usar <<< :

$ for i in {1..10}; do 
    ( time echo $OUTPUT | tr -d "\"\`'" > /dev/null ) 2>&1
done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}'; 
0.0025
$ for i in {1..10}; do 
    ( time tr -d "\"\`'" <<<$OUTPUT > /dev/null ) 2>&1 
  done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}'; 
0.0029

Dado que la diferencia es pequeña, ejecuté las pruebas anteriores 10 veces para cada una de las dos y resulta que la más rápida es de hecho con la que tenías que empezar:

echo $OUTPUT | tr -d "\"\`'" 

Sin embargo, esto cambia cuando se tiene en cuenta la sobrecarga de asignar a una variable, aquí, usar tr es un poco más lento que el simple reemplazo:

$ for i in {1..10}; do
    ( time OUTPUT=${OUTPUT//[\'\"\`]} ) 2>&1
  done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}'; 
0.0032

$ for i in {1..10}; do
    ( time OUTPUT=$(echo $OUTPUT | tr -d "\"\`'")) 2>&1
  done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}'; 
0.0044

Entonces, en conclusión, cuando simplemente desee ver los resultados, use tr pero si desea reasignar a una variable, usar las funciones de manipulación de cadenas del shell es más rápido, ya que evitan la sobrecarga de ejecutar un subshell separado.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım