2017-02-20 259 views
3

我有一個從STDOUT中捕獲的多行變量。
我想插入一個echo命令使用這個多行變量在第15行中的另一個腳本(目標)。在sed命令中使用多行變量

#!/bin/bash 
TEST=`cat foo` 

echo "$TEST" 

sed -i "15i echo \"$TEST\" > someotherfile" target 

富的內容:

apples 
oranges 
bananas 
carrots 

我想在讀取線sed命令提要,我證實了我富了:

[email protected]$ cat foo | tr -cd '\n' | wc -c 
4 

當我跑我的test.sh腳本,我看到$TEST中有什麼,但是我得到了sed命令的錯誤:

[email protected]$ ./test.sh 
apples 
oranges 
bananas 
carrots 
sed: -e expression #1, char 18: unknown command: `o' 

我在做什麼錯? 在此先感謝。

+0

您可以添加完整的樣本輸入/輸出嗎? 'TEST'具有多行字符串值,並且你在前後添加一些字符串......所以我不太清楚......從文件中插入內容,使用'r'命令...'sed' 14r foo'target' - >從第15行開始插入文件foo的內容以輸入文件目標 – Sundeep

回答

1

嘗試:

解決方法1:

awk 'NR==15{print;system("cat foo");next} 1' Input_file 

無需得到完整的文件到一個變量,我們可以簡單地打印您要打印哪個INPUT_FILE線。

溶液2:

line=15; sed -e "${line}r foo" target 

或(腳本模式)

cat script.ksh 
line=15; 
sed -e "${line}r foo" target 

哪里哪里要插入從另一個文件中的行,你可以改變線的數量。

0

sed中的i命令會插入以換行符結尾的文本行,直到不以反斜槓結尾的行。 ac命令是相似的。經典sed不喜歡第一行出現在與i命令相同的行; GNU sed沒有那麼挑剔。

如果你手工編寫的命令,你需要寫:

15i\ 
echo "apples\ 
oranges\ 
bananas\ 
carrots" > someotherfile 

在現在的問題是「你怎麼想創建這個給定的文件foo包含名稱的列表?」。有時,使用sed生成sed腳本很有用。但是,如果您需要在受到i(或ac)命令支持的行末尾反斜槓,並且繞過此問題更簡單,那麼它也可能錯綜複雜。

{ 
    echo "15i\\" 
    sed -e '1s/^/echo "/' -e 's/$/\\/' -e '$s/\\$/" > someotherfile/' foo 
} | sed -f /dev/stdin target 

sed GNU可以讀取使用-f -標準輸入其腳本; BSD(macOS)sed不喜歡,但是您可以使用-f /dev/stdin代替(它也適用於GNU sed),至少在有/dev/stdin的系統上。

0

GNUsed被假定,正如問題中使用的語法所暗示的。

#!/bin/bash 

# Read contents of file 'foo' into shell variable $test. 
test=$(<foo) 

# \-escape the newlines in $test for use in Sed. 
testEscapedForSed=${test//$'\n'/\\$'\n'} 

sed -i "15i echo \"$testEscapedForSed\" > someotherfile" target 
  • 你的問題是,經過多線字符串sed功能,諸如i(插入)需要嵌入在這些字符串是\轉義新行,以便sed知道字符串結束並附加命令(如果有的話)開始。

  • 還要注意:

0

有趣的問題。 正如已經提到的,sed能夠在其他文件中插入多行文本的全部內容是,這種新的多行文本實際上必須具有分行\n的換行符。

所以我們可以用sed來真正的新行字符轉換爲文字\n

$ a=$(tr '\n' '\\' <file3 |sed 's#[\]$##' |sed "s#[\]#\0n#g") 
#Alternative: a=$(sed "s#[\]#\0n#g" <(sed 's#[\]$##' <(tr '\n' '\\' <file3))) 
$ echo "$a" 
apples\noranges\nbananas\ncarrots 

這個翻譯是如何工作的:
*首先,我們全部更換新的生產線使用tr
*然後一個反斜槓我們從字符串的末尾刪除反斜槓
*然後我們用反斜槓和n個字符替換所有其他反斜槓。

因爲現在變量$a所包含的行之間的文字\n,sed的將他們帶回轉化爲實際工作中的新線路:

$ cat file4 
Line1 
line2 
line3 
$ sed "2i $a" file4 
Line1 
apples 
oranges 
bananas 
carrots 
line2 
line3 

結果:

$ a=$(tr '\n' '\\' <file3 |sed 's#[\]$##' |sed "s#[\]#\0n#g") 
$ sed "2i $a" file4 

Mutliline置換可以用兩個命令來實現

sed 2i表示在第2行之前插入文本。可以使用2a以便在第2行之後插入某些內容。

備註:
根據this post這似乎是一式兩份,新線字面\ n翻譯似乎可以只進行:

a=$(echo ${a} | tr '\n' "\\n") 

但這種方法從來沒有在我的系統工作。

備註2:
桑達操作sed "2i $a" = 2行之前插入變量$ a,也可以表示爲sed "1 s/.*/\0\n$a/" =具有相同的字符\0加上一個新的線\n加的可變$a內容替換第一行的所有字符=>在line1之後插入$ a =在line2之前插入$ a。