Usa sed su una variabile stringa anziché su un file


30

Mi è stato detto che era possibile, ma senza un singolo esempio funzionante, che sedpuò leggere da una variabile stringa senza la necessità di un file di input. Devo ancora farlo funzionare. Per sicurezza generale, sto scrivendo la $PATHvariabile su un'altra variabile, mentre mi incaglio su questo, perché non ho bisogno di altri problemi per sorgere fino a quando non so esattamente come farlo.

Considera quanto segue:

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

ciò fallisce con: nessun file o directory.

Eccone alcuni 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ò anche funzionare? Preferirei non dover scrivere file di cui non ho bisogno solo per poter usare sed. Per questo esempio particolare, se ~$x=$PATH ~$sed -i 's/:/ /g' $xeffettivamente funzionasse come 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 utilizzare in comandi futuri, come ls $x


1
x=$(echo "$x" | sed 's/:/ /g')?
heemayl

Risposte:


16

Può essere:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games

@jOh --- nota che sedqui non funziona sulla "variabile stringa" (?), ma sull'input standard --- che è come dovrebbe essere.
Rmano,

penso che farò una richiesta di funzionalità agli sviluppatori sed
j0h

4
@ j0h questo non ha nulla a che fare con sed, è una questione di come la shell reindirizza l'input. sedgestisce i flussi di input e li legge attraverso i suoi input standard. Che siano file o meno è irrilevante. Può accettare qualsiasi cosa purché arrivi attraverso l'input standard.
terdon,

38

Questo non ha nulla a che fare con sedtale, si applica a qualsiasi programma che legge input standard. Ad ogni modo, quello che stavi cercando è

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

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

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

Nota che potresti anche averlo fatto

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

Infine, non hai davvero bisogno seddi questo. Puoi fare tutto direttamente in bash:

echo "${PATH//:/ }"

Quanto sopra è un costrutto di sostituzione bash. Data una variabile $var, un modello pate una sostituzione ( rep), per sostituire tutte le occorrenze di patcon rep, lo faresti

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

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

echo "${var/pat/rep}"

2
Grazie per "costruzione sostitutiva bash". Sono stato in grado di utilizzare: "$ {1 / da / a}" in una funzione Bash per modificare il primo argomento in parametri successivi.
AAAfarmclub
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.