对字符串变量而不是文件使用sed


30

有人告诉我有可能,但是没有一个单独的示例,它sed可以从字符串变量读取而无需输入文件。我还没有开始工作。为了安全起见,我将$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


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

Answers:


16

也许:

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

@jOh ---注意,sed这里不是在“字符串变量”(?)上工作,而是在标准输入上工作---应该是这样。
Rmano

我认为我会向sed开发人员提出功能要求
j0h 2015年

4
@ j0h与无关sed,这是shell如何重定向输入的问题。sed处理输入流,并通过其标准输入读取它们。它们是否为文件无关紧要。只要它通过标准输入,它就可以接受任何东西。
terdon 2015年

38

与此无关sed,它适用于任何读取标准输入的程序。无论如何,您要找的是

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

没有理由要保存在另一个变量中,以这种方式进行的任何操作都不会影响存储在该变量中的值。=为此,您需要赋值运算符()。上面使用的语法称为“此处字符串”,特定于bash,ksh和zsh。它用于将变量的值作为输入传递给从标准输入读取的程序。

在U&L上写了一个答案,其中列出了所有与此类似的Shell运算符。您可能想看看。

请注意,您也可以完成

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

最后,您实际上根本不需要sed。您可以直接在bash中完成整个操作:

echo "${PATH//:/ }"

上面是bash替换构造。给定一个变量$var,模式pat和替换(rep),以取代所有出现patrep,你会怎么做

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

带有单个斜杠的相同内容仅替换第一次出现的情况:

echo "${var/pat/rep}"

2
感谢您的“替换替换结构”。我能够在Bash函数中使用:“ $ {1 / from / to}”将第一个参数更改为后续参数。
AAAfarmclub
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.