2014-07-03 54 views
-1

我有這個代碼和平:sed的 - 未結束的'S'命令

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例如,字符串「圓周率」,但它給:

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

爲什麼? 謝謝。

+2

goterm的價值是什麼? –

+0

@Avinash拉傑,真的嗎?你不能看到goterm是文件BP.csv的第一列嗎? – user2979409

+1

Ick,你知道這兩個'awk'命令都是從'stdin'讀取的,而不是'$ line'變量,對吧? – ams

回答

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。 awk實際上是針對stdin運行的,所以'$ goterm'包含了從第2行開始的第一列值的換行分隔列表。由於's'表達式在中間有一個非轉義字面換行,sed說它沒有終止。 –

+0

@thatotherguy你是對的,否則awk會掛起等待輸入。 – Tiago

0

我會重組這整個事情更是這樣的:

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

沒有理由awk的事情,作爲bashread如果你給它多個變量,內建函數將爲你做基本的場分割。此外,您還沒有使用name,所以不需要。 cat也是不必要的。

根據您的具體使用情況,即使是grep可能是不必要的,使內部命令只是sed -ne "s/${goterm}/pi/gp" GOEA.csv。除非你的宗旨,爲grep -w是消除線路,其中${goterm}是一個詞,而不是整個詞的一個子......

以供將來參考,插入你在你的腳本環上方的set -x會告訴你是確切的命令正在運行,以便您可以將它們與您的期望進行比較。

1

讓我們來收拾這個代碼位:

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

的問題是,你的awk語句正試圖從STDIN就像你while是做閱讀。您正在閱讀相同的輸入流。

你想要做的是從你的線拉出值。我使用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他們,那麼我用pi代替$goterm-n表示不打印出行,因爲sed處理它們,並且p表示打印出替代品所在的行。

順便說一句,csv作爲文件後綴意味着逗號分隔值但既不是文件看起來是逗號分隔。這些選項卡是分隔每個字段嗎?如果是這樣,您需要將$IFS修改爲製表符。