I have been told it was possible, but without a single working example, that sed
can read from a string variable without need for an input file. I have yet to get it to work.
For general safety, I’m writing the $PATH
variable to another variable, as I mess with this, because I don’t need other problems to arise until I know exactly how to do this.
Consider the following:
~$x=$PATH
~$sed -i 's/:/ /g' $x
this fails with: No such file or directory.
Here are some others I have tried:
~$ 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
Can this even work? I would prefer not to need to write files I don't need just so I can use sed. For this particular example, if ~$x=$PATH ~$sed -i 's/:/ /g' $x
actually worked the way I would have hoped, I would get:
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games
which I could then assign to a variable, and use in future commands, like ls $x
This has nothing to do with
sed
as such, it applies to any program that reads standard input. Anyway, what you were looking for isThere's no reason to save in another variable, nothing you do this way will affect the value stored in the variable. You need the assignment operator (
=
) for that. The syntax used above is called a "here string" and is specific to bash, ksh and zsh. It serves to pass a variable's value as input to a program that reads from standard input.I have written up an answer on U&L that lists all the various shell operators like this one. You might want to have a look.
Note that you could also have done
Finally, you really don't need
sed
at all for this. You can do the whole thing in bash directly:The above is a bash replacement construct. Given a variable
$var
, a patternpat
and a replacement (rep
), to replace all occurrences ofpat
withrep
, you would doThe same thing with a single slash replaces only the first occurrence:
May be: