问题描述
我被告知这是可能的,但没有一个工作示例,sed
可以从字符串变量中读取而不需要输入文件。我还没有让它发挥作用。 \n为了一般安全,我将 $PATH
变量写入另一个变量,因为我搞乱了这个,因为在我确切知道如何做到这一点之前,我不需要出现其他问题。
考虑以下:
~$x=$PATH
~$sed -i 's/:/ /g' $x
失败并显示:没有这样的文件或目录。
以下是我尝试过的其他一些:
~$ 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
这能行得通吗?我宁愿不需要写入我不需要的文件,这样我就可以只使用 sed。对于这个特定示例,如果 ~$x=$PATH ~$sed -i 's/:/ /g' $x
确实按我希望的方式工作,我会得到:
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games
然后我可以将其分配给变量,并在将来的命令中使用,例如 ls $x
最佳方案
这与 sed
无关,它适用于读取标准输入的任何程序。不管怎样,你正在寻找的是
sed 's/:/ /g' <<<"$PATH"
没有理由保存在另一个变量中,这样做不会影响存储在变量中的值。为此,您需要赋值运算符( =
)。上面使用的语法称为 “here string”,特定于 bash、ksh 和 zsh。它用于将变量的值作为输入传递给从标准输入读取的程序。
我已经写了 an answer on U&L ,其中列出了所有像这样的各种 shell 操作符。您可能想看一下。
请注意,您也可以这样做
echo "$PATH" | sed 's/:/ /g'
最后,您实际上根本不需要 sed
。您可以直接在 bash 中完成整个操作:
echo "${PATH//:/ }"
以上是 bash 替换结构。给定一个变量 $var
,一个模式 pat
和一个替换( rep
),用 rep
替换所有出现的 pat
,你会这样做
echo "${var//pat/rep}"
带有单个斜杠的相同内容仅替换第一次出现的内容:
echo "${var/pat/rep}"
次佳方案
或许:
~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games