2017-02-20 261 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。