script examples bash sed io

bash - examples - Ejecutando sed en una cuerda, beneficio de usar "echo"+"pipe" sobre "<<<"



use sed command in shell script (3)

Esta pregunta ya tiene una respuesta aquí:

Comúnmente veo personas manipulando cadenas usando sed de la siguiente manera:

echo "./asdf" | sed -n -e "s%./%%p"

Recientemente aprendí que también puedo hacer:

sed -n -e "s%./%%p" <<< "./asdf"

¿Hay alguna razón para evitar esto último? Por ejemplo, ¿es un comportamiento específico de bash?


¿Cómo debo recortar ./ desde el comienzo de una ruta (o realizar otras manipulaciones simples de cadenas)?

La sintaxis incorporada de Bash para esto se llama expansión de parámetros . ${s#./} ampliará $s con cualquier interno ./ trimmed interno al shell, sin subprocesos u otros gastos generales. BashFAQ # 100 cubre muchas operaciones adicionales de manipulación de cadenas.

¿Cuáles son las diferencias entre echo "$s" | ... echo "$s" | ... y ... <<<"$s" ?

  1. Portabilidad

    Como ha notado, <<< no está disponible en POSIX sh; esta es una extensión ksh también disponible en bash y zsh.

    Dicho esto, si necesita portabilidad, el equivalente multilínea no está muy lejos:

    ... <<EOF $s EOF

  2. Uso del disco

    Tal como lo implementa bash (y como detalle de implementación sujeto a cambios), <<< crea un archivo temporal, lo rellena y lo redirecciona. Si su TEMPDIR no está en un sistema de archivos en la memoria, esto puede ser más lento o puede generar abandono.

  3. Sobrecarga del proceso

    Una tubería, como en echo foo | ... echo foo | ... , crea una subcapa - se abre un proceso completamente nuevo, responsable de ejecutar echo y luego salir. Cuando está ejecutando result=$(echo "$s" | ...) , esa interconexión se encuentra en una subcategoría de su shell principal, y el elemento primario tiene que leer el resultado.

    Los unixlikes modernos hacen un gran esfuerzo para hacer que la fork() de un subproceso tenga un bajo nivel de sobrecarga en la medida de lo posible, pero incluso puede sumarse en una operación realizada en un ciclo, y en plataformas como Cygwin puede ser incluso más significativo.

  4. errores de echo

    Por último, pero no menos importante, <<<"$s" representará cualquier contenido de la variable con precisión, con la excepción de que puede agregar una nueva línea al final. Por el contrario, echo tiene un gran margen de maniobra en su comportamiento específico: puede aceptar ampliaciones de barra invertida o no según el cumplimiento de las extensiones XSI opcionales del estándar (y la presencia o ausencia de la extensión extendida, pero totalmente no conforme de -e , y / o indicadores de tiempo de ejecución que lo deshabilitan); la capacidad de evitar la adición de líneas nuevas con -n no está garantizada por el estándar; &do. Incluso si está utilizando una interconexión, es mejor usar printf :

    # emit *exactly* the contents of "$s", with no newline added printf ''%s'' "$s" | ... # emit the contents of "$s", with an added trailing newline printf ''%s/n'' "$s" | ... # emit the contents of "$s", with ''/t'', ''/n'', ''/b'' &c replaced, and no added newline printf ''%b'' "$s" | ...


Creo que hay dos cosas en juego aquí.

  1. <<< vs. gasoductos
  2. sed (u otro comando externo) vs expansión de parámetros

Si puede hacer algo con la expansión, es muy probable que sea mucho más rápido, ya que guarda un comando externo que se inicia.

Sin embargo, no todo se puede hacer con la expansión. Así que puede que tenga que usar un comando externo y usar como entrada algo que tiene en una variable. En este caso, tendrá que hacer su elección en función de consideraciones de portabilidad. En cuanto al rendimiento, si es importante, probablemente debería probar en su contexto lo que funciona mejor.


Usar sed en absoluto no es deseable si puede ser ayudado (ver la respuesta de Charles Duffy); pon la cadena en una variable y deja que el shell lo haga con la expansión de parámetros compatible con POSIX.

$ s="./asdf" $ echo "${s#./}" asdf