Usa sed en una variable de cadena en lugar de un archivo

17

Me han dicho que era posible, pero sin un solo ejemplo de trabajo, ese sed puede leer de una variable de cadena sin necesidad de un archivo de entrada. Todavía tengo que hacerlo funcionar. Para seguridad general, estoy escribiendo la variable $PATH a otra variable, ya que me equivoco con esto, porque no necesito que surjan otros problemas hasta que sepa exactamente cómo hacer esto.

Considere lo siguiente:

~$x=$PATH
~$sed -i 's/:/ /g' $x

esto falla con: No hay tal archivo o directorio.

Aquí hay algunos otros que he intentado:

~$ sed -i 's/:/ /g' | (read x) 
sed: no input files
~$ sed -i 's/:/ /g' | (read $x) 
bash: read: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' | $(read x) 
sed: no input files
~$ sed -i 's/:/ /g' | $(read $x) 
bash: read: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' < $(read $x) 
bash: read: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
bash: $(read $x): ambiguous redirect
~$ sed -i 's/:/ /g' < read $x 
bash: read: No such file or directory
~$ sed -i 's/:/ /g' < (read x) 
bash: syntax error near unexpected token '('
~$ sed -i 's/:/ /g' < $((read x)) 
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: syntax error: operand expected (error token is "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' < $((read $x)) 
bash: read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: division by 0 (error token is "usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' << $((read $x)) 
> ;^C
~$ sed -i 's/:/ /g' << $(read $x)
> ;^C
~$ sed -i 's/:/ /g' $x
sed: can't read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < $x
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < echo $x
bash: echo: No such file or directory
~$ sed -i 's/:/ /g' |  echo $x
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
sed: no input files

¿Esto puede funcionar? Preferiría no tener que escribir archivos que no necesito solo para poder usar sed. Para este ejemplo en particular, si ~$x=$PATH ~$sed -i 's/:/ /g' $x realmente funcionó como yo esperaba, obtendría:

/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games

que luego podría asignar a una variable y usar en futuros comandos, como ls $x

    
pregunta j0h 10.03.2015 - 21:21

2 respuestas

15

Puede ser:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games
    
respondido por el bolichep 10.03.2015 - 21:38
30

Esto no tiene nada que ver con sed como tal, se aplica a cualquier programa que lea la entrada estándar. De todos modos, lo que estabas buscando es

sed 's/:/ /g' <<<"$PATH"

No hay razón para guardar en otra variable, nada de lo que haga afectará el valor almacenado en la variable. Necesitas el operador de asignación ( = ) para eso. La sintaxis utilizada anteriormente se denomina "cadena aquí" y es específica de bash, ksh y zsh. Sirve para pasar el valor de una variable como entrada a un programa que lee de la entrada estándar.

Escribí una respuesta en U & amp; L que enumera todos los diversos operadores de shell como este. Es posible que desee echar un vistazo.

Tenga en cuenta que también podría haber hecho

echo "$PATH" | sed 's/:/ /g' 

Finalmente, realmente no necesitas sed para nada. Puedes hacer todo en bash directamente:

echo "${PATH//:/ }"

Lo anterior es una construcción de reemplazo bash. Dada una variable $var , un patrón pat y un reemplazo ( rep ), para reemplazar todas las apariciones de pat con rep , harías

echo "${var//pat/rep}"

Lo mismo con una sola barra reemplaza solo la primera aparición:

echo "${var/pat/rep}"
    
respondido por el terdon 10.03.2015 - 22:34

Lea otras preguntas en las etiquetas