Usa sed su una variabile stringa piuttosto che su un file

17

Mi è stato detto che era possibile, ma senza un singolo esempio funzionante, che sed può leggere da una variabile stringa senza necessità di un file di input. Devo ancora farlo funzionare. Per motivi di sicurezza generale, sto scrivendo la variabile $PATH su un'altra variabile, dato che ho problemi con questo, perché non ho bisogno che sorgano altri problemi finché non so esattamente come farlo.

Considera quanto segue:

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

questo fallisce con: nessun file o directory.

Ecco alcuni altri che ho provato:

~$ 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

Può funzionare anche questo? Preferirei non dover scrivere file che non ho bisogno solo per usare sed. Per questo particolare esempio, se ~$x=$PATH ~$sed -i 's/:/ /g' $x ha effettivamente funzionato nel modo in cui avrei sperato, otterrei:

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

che potrei quindi assegnare a una variabile e usare in futuri comandi, come ls $x

    
posta j0h 10.03.2015 - 22:21

2 risposte

15

Può essere:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games
    
risposta data bolichep 10.03.2015 - 22:38
30

Questo non ha nulla a che fare con sed in quanto tale, si applica a qualsiasi programma che legge input standard. Ad ogni modo, quello che cercavi è

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

Non c'è motivo di salvare in un'altra variabile, nulla che fai in questo modo influirà sul valore memorizzato nella variabile. Per questo è necessario l'operatore di assegnazione ( = ). La sintassi utilizzata sopra è denominata "stringa qui" ed è specifica per bash, ksh e zsh. Serve per passare il valore di una variabile come input per un programma che legge dallo standard input.

Ho scritto una risposta su U & amp; che elenca tutti i vari operatori di shell come questo. Potresti dare un'occhiata.

Nota che avresti potuto anche fare

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

Infine, davvero non hai bisogno di sed per questo. Puoi fare tutto direttamente in bash:

echo "${PATH//:/ }"

Quanto sopra è un costrutto di sostituzione bash. Dato una variabile $var , un modello pat e una sostituzione ( rep ), per sostituire tutte le occorrenze di pat con rep , dovresti fare

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

La stessa cosa con una singola barra sostituisce solo la prima occorrenza:

echo "${var/pat/rep}"
    
risposta data terdon 10.03.2015 - 23:34

Leggi altre domande sui tag