sed - unterminated的命令

时间:2014-07-03 15:14:07

标签: bash sed

我有这种代码的和平:

cat BP.csv | while read line ; do
    goterm=$(awk '{print $1}') ;
    name=$(awk '{print $2}') ;
    grep -w "$goterm" GOEA.csv | sed "s/$goterm/pi/g" ;
done

文件BP.csv具有以下格式:

GO:0008283  cell proliferation
GO:0009405  pathogenesis
GO:0010201  response to continuous far red light stimulus by the high-irradiance response system
GO:0009641  shade avoidance

虽然GOEA.csv具有以下格式:

4577    GO:0006807  0.994   2014_06_01
4577    GO:0016788  0.989   2014_06_01
4577    GO:0043169  0.977   2014_06_01
4577    GO:0043170  0.963   2014_06_01

sed不起作用。我想将GO:0043170更改为字符串“pi”,但它会给出:

sed: -e expression #1, char 12: unterminated `s' command

为什么呢? 感谢。

3 个答案:

答案 0 :(得分:3)

您在没有输入的情况下运行awk命令,试试这个:

cat BP.csv | while read line ; do
    goterm=$(awk '{print $1}' <<< "$line") ;
    name=$(awk '{print $2}' <<< "$line" ) ;
    grep -w "$goterm" GOEA.csv | sed "s/$goterm/pi/g" ;
done

答案 1 :(得分:1)

让我们稍微清理一下这段代码:

while read goterm name
do
    grep -w "$goterm" GOEA.csv | sed "s/$goterm/pi/g"
done < BP.cvs

问题是你的awk语句试图像你while那样从STDIN读入。您正在读取相同的输入流。

您要做的是从您的行中提取值。我正在使用read来执行此操作。 read语句使用$IFS中的值来分隔输入。这通常是空格,制表符和换行符。 read读取您在该行上放置的每个变量,读取的最后一个值包含该行的其余部分。

因此:

while read line

读取整行:

while goterm name

将打破

goterm="GO:0008283"
name="cell proliferation"

还有一件事。当您同时使用grepsed时,您可能只能使用sed

while read goterm name
do
    sed -n "/$goterm/s/$goterm/pi/gp" GOEA.csv
done < BP.csv

sed命令的格式为:

/lines/command/parameters/

所以,我正在搜索其中包含$goterm的行,然后我用$goterm替换pi-n表示不会在sed处理行时打印出行,而p表示打印出替换所在的行。

顺便说一句,csv作为文件后缀意味着逗号分隔值,但这两个文件看起来都不是逗号分隔的。这些标签是否分隔每个字段。如果是这样,您需要修改$IFS作为标签。

答案 2 :(得分:0)

我会重整整个事情:

while read goterm restofline
do
  grep -w "${goterm}" GOEA.csv | sed -e "s/${goterm}/pi/g"
done < BP.csv

没有理由awk内容,因为bash read内置将为您提供基本字段拆分,如果您给它多个变量。此外,您无论如何都不使用name,因此不需要它。 cat也是不必要的。

根据您的确切用例,即使是grep也可能是不必要的,因此内部命令只需sed -ne "s/${goterm}/pi/gp" GOEA.csv。除非你grep -w的目的是消除${goterm}是一个单词的子串而不是整个单词的行......

为了将来参考,在您的脚本中在循环上方插入set -x会向您显示正在运行的命令,以便您可以将它们与您的期望进行比较。