2014-09-24 45 views
0

数我有一定的行文件,比方说......更换整条生产线正从可变

AAA BBB CCC 

我需要更换整条生产线,发现它之后,所以我做:

q1=`grep -Hnm 1 "AAA" FILE | cut -d : -f 2` 

输出我第一次出现(在q1)的行号,因为它有不止一次出现,现在,这里出现我的问题...在上一步中,我使用此sed来替换某一行在文件中:

sed -e '3s/.*/WHATEVER/' FILE 

要更换(在本例中,3号线)与任何完整的线,但现在如果我尝试使用$ Q1,而不是“3”表示该行号这是行不通的:

sed -e '$q1s/.*/WHATEVER/' FILE 

这可能是一个愚蠢的语法错误,任何帮助是值得欢迎的;在此先感谢

+0

而不是使用''grep'和cut'的' sed',为什么不使用'awk'? – 2014-09-24 18:55:23

回答

0

尝试: sed -e '${q1}s/.*/WHATEVER/' FILE

+0

爱你的兄弟,工作就像一个魅力!非常感谢! – Ghost 2014-09-24 17:47:01

+1

更好地使用双引号而不是单引号,因此可以扩展shell变量。 – 2014-09-24 17:49:13

+0

是的,也是这样= = – Ghost 2014-09-24 18:57:59

0

我会用awk为此:

awk '/AAA/ && !r {print "WHATEVER"; r=1; next} {print}' <<END 
a 
b 
AAA BBB CCC 
d 
e 
AAA foo bar 
f 
END 
a 
b 
WHATEVER 
d 
e 
AAA foo bar 
f 
+0

awk对sed有什么好处? – Ghost 2014-09-24 18:02:42

+0

您可以在awk中使用变量,而不是sed。所以你可以知道它是否是你第一次看到这种模式。 – 2014-09-24 18:07:14

0

如果要替换文件中的字符串的第一次出现,你可以使用这个awk脚本:

awk '/occurrence/ && !f++ {print "replacement"; next}1' file 

替换将仅在第一次打印,因为!f++只会评估为真(在随后的评估中,f将大于零,因此!f将为false。最后的1总是如此,所以对于除匹配的行以外的每一行,awk都执行默认操作并打印行。

测试出来:

$ cat file 
blah 
blah 
occurrence 1 and some other stuff 
blah 
blah 
some more stuff and occurrence 2 
blah 
$ awk '/occurrence/ && !f++ {print "replacement"; next}1' file 
blah 
blah 
replacement 
blah 
blah 
some more stuff and occurrence 2 
blah 

的“更新换代”的字符串可以很容易地设置一个shell变量的下列方式值:

awk -v rep="$r" '/occurrence/ && !f++ {print rep; next}1' file 

其中$r是一个shell变量。

使用与上面相同的文件和实例变量在您的评论:

$ q2="x=\"Second\"" 
$ awk -v rep="$q2" '/occurrence/ && !f++ {print rep; next}1' file 
blah 
blah 
x="Second" 
stuff 
blah 
blah 
some more stuff and occurrence 2 
blah 
+0

遇到这个问题...在这种情况下,我的“替换”是一个变量q2 =“x = \”Second \“”,但是替换时只写入“Second”而不是存储在q2处的完整字符串。 – Ghost 2014-09-24 19:06:43

+0

这很奇怪,它适用于我,请参阅我的答案的更新。 – 2014-09-24 19:11:12

+0

现在完美更新!而且是的,看起来awk可以节省很多线条,但我仍然不是专家;)。非常感谢!!! – Ghost 2014-09-24 19:42:48

0
sed "${q1} c\ 
WHATEVER" YourFile 

,但你可以直接使用

sed '/YourPatternToFound/ {s/.*/WHATEVER/ 
:a 
N;$!ba 
}' YourFile