2016-01-13 29 views
0

我有,在某些時候包含諸如以下行文件:Bash - 如何用變量中定義的多行代替以模式開頭的單行?

VIRTUAL_ENV="/afs/sern.ch/user/l/lronhubbard/virtual_environment" 

它是與VIRTUAL_ENV開頭的文件中唯一的行。使用腳本,我想用下面幾行代替這一行:

directory_bin="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 
directory_env="$(dirname "${directory_bin}")" 
VIRTUAL_ENV="${directory_env}" 

這怎麼可以做到?

首先,我得保存在一個腳本文件在這裏更換線路:

IFS= read -d '' text << "EOF" 
directory_bin="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 
directory_env="$(dirname "${directory_bin}")" 
VIRTUAL_ENV="${directory_env}" 
EOF 

接下來,我可以替換別的文件中的線(在這裏,xxx)使用sed

sed -i "s/^VIRTUAL_ENV.*/xxx/g" test.txt 

現在,我怎麼可以使用這裏定義文檔變量${text},其所有新行和諸如此類的東西,而不是xxxsed命令?


編輯:繼rslemos的建議,我已經實現了使用,而不是在這裏文檔的臨時文件如下:

#!/bin/bash 

temporary_filename="$(tempfile)" 

cat > "${temporary_filename}" << "EOF" 
directory_bin="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 
directory_env="$(dirname "${directory_bin}")" 
VIRTUAL_ENV="${directory_env}" 
EOF 

sed -i "/^VIRTUAL_ENV.*/ { 
    r ${temporary_filename} 
    d 
}" test.txt 

rm "${temporary_filename}" 

我還是想知道如何使用此文檔直接讓我不會不必要地使用硬盤。

+0

請不要發佈答案作爲問題的一部分。如果您想添加自己的答案,請將其作爲答案進行發佈。 – tripleee

回答

2

我會去單獨sed

/^VIRTUAL_ENV/{ 
r source.txt 
d 
} 

其中的Source.txt就是說謊的新生產線,以取代開頭「VIRTUAL_ENV」一個行的文件。

如果你真的需要新的行(source.txt)作爲here文檔,/dev/fd/0技巧將起作用(至少在Linux中)。但你也可以結合mktempmkfifo

編輯

,解決「我還是想知道如何直接使用此文件」:

!/bin/bash 

sed -e '/^VIRTUAL_ENV/{' -e 'r /dev/fd/0' -ed -e'}' test.txt << "EOF" 
directory_bin="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 
directory_env="$(dirname "${directory_bin}")" 
VIRTUAL_ENV="${directory_env}" 
EOF 

不是非常便攜,因爲/dev/fd/0部分(雖然在Linux中工作)。

0

許多sed方言讓你逃脫換行符替換:

sed -i 's/^VIRTUAL_ENV.*/directory_bin="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"\ 
directory_env="$(dirname "${directory_bin}")"\ 
VIRTUAL_ENV="${directory_env}"/' test.txt 

這是一個單引號的字符串跨越三線,用反斜槓添加延續在每一個內部行的邊界。

這並不是每個sed變種的便攜式,但在* BSD(包括OSX)和Linux至少可以正常工作。順便說一句,你也可以簡單地把所有這些命令放在一行上,並用分號隔開。

+0

'/ g'的標誌在這裏顯然沒用,所以我把它拿出來了。 – tripleee

1

這可能會爲你工作(GNU sed的&的bash):

cat <<\! | sed $'/PATTERN/{r /dev/stdin\n;d}' file 
HERE DOCUMENT 
STUFF 
HERE 
! 

使用cat到管stdin到sed命令,並把它讀作使用r命令的文件。

N.B. \!引用此處文檔中的所有文本均使用!來插入變量。 $'...'允許需要換行符的命令(即sed命令,例如r,a,i,c,R,w,W)被寫爲一行。

相關問題