我有一个文件foo
我想编辑。我想替换文件的所有行
在某个模式匹配之前$node_(2)
$node_(0) set X_ 46.188445620285734
$node_(0) set Y_ 400.0
# $ns_ at 0.0 "$node_(0) setdest 46.188445620285734 400.0 0.0"
$ns_ at 4.230260628522046 "$node_(0) setdest 140.0 400.0 11.073898626729083"
$ns_ at 12.70167232749509 "$node_(0) setdest 140.0 293.81155437971427 11.073898626728642"
# $ns_ at 22.290747430998636 "$node_(0) setdest 140.0 293.81155437971427 0.0"
$ns_ at 24.512130351924498 "$node_(0) setdest 140.0 121.22627768528247 11.143254728766196"
$node_(1) set X_ 284.3754249089888
$node_(1) set Y_ 400.0
$ns_ at 0.0 "$node_(1) setdest 358.5058741786957 400.0 10.938908248230844"
# $ns_ at 6.776768539190925 "$node_(1) setdest 358.5058741786957 400.0 0.0"
$ns_ at 8.52331532068547 "$node_(1) setdest 400.0 400.0 11.27995015881709"
$ns_ at 12.201888828288247 "$node_(1) setdest 400.0 341.4941258213043 11.279950158817115"
# $ns_ at 17.388602719303435 "$node_(1) setdest 400.0 341.4941258213043 0.0"
$ns_ at 22.22922653365822 "$node_(1) setdest 400.0 141.4941258213043 11.258336966410015"
$node_(2) set X_ 270.0 //so basically here is the pattern match
$node_(2) set Y_ 293.0222761518543
.
.
.
该文件应该如下所示
$node_(0) set X_ 10.0
$node_(0) set Y_ 10.0
$node_(1) set X_ 510.0
$node_(1) set Y_ 510.0
$node_(2) set X_ 270.0 //pattern and everything after it is left intact
$node_(2) set Y_ 293.0222761518543
.
.
.
我尝试了用sed
sed -i -e '/$node_(0)/,/$node_(2)/c\$node_(0)\ set X_ 10.0 \n$node_(0) set Y_ 10.0\n$node_(1) set X_ 510.0\n$node_(1) set Y_ 510.0' foo
但它会完全删除第一个$node_(2)
行。此外,$node_(2)
之前的行数会针对每个新foo
文件进行更改,因此我无法计算每次替换的行数。
答案 0 :(得分:2)
只需颠倒逻辑。
sed -n '1i \
$node_(0) set X_ 10.0\
$node_(0) set Y_ 10.0\
$node_(1) set X_ 510.0\
$node_(1) set Y_ 510.0
/[$]node_(2)/,$p' file
1
是一个地址表达式,用于选择第一行,i
是一个插入文本的命令。唉,i
命令没有完全标准化,因此实现细节和语法(特别是插入多行)在不同平台之间有所不同。为了易读性和可移植性,可以切换到Perl:
perl -i -ne 'BEGIN { print <<__the_end_of_the_BEGIN__; }
\$node_(0) set X_ 10.0
\$node_(0) set Y_ 10.0
\$node_(1) set X_ 510.0
\$node_(1) set Y_ 510.0
__the_end_of_the_BEGIN__
$p=1 if /^\$node_\(2\)/;
print if $p;' file
您可以编写一个非常相似的Awk脚本,但不能移植支持sed -i
/ perl -i
等文件的就地编辑。
Perl使用美元符号作为标量变量的标志,因此必须将它们转义为字面打印,正则表达方言与传统sed
或Awk不同(并且功能更强大),但是唯一不同的是,括号需要被反斜或以其他方式逃脱。
答案 1 :(得分:2)
如果我将要插入的行放入单独的文件replace
:
$node_(0) set X_ 10.0
$node_(0) set Y_ 10.0
$node_(1) set X_ 510.0
$node_(1) set Y_ 510.0
我可以这样做:
$ sed -n '/\$node_(2)/,$p' infile | cat replace -
$node_(0) set X_ 10.0
$node_(0) set Y_ 10.0
$node_(1) set X_ 510.0
$node_(1) set Y_ 510.0
$node_(2) set X_ 270.0 //so basically here is the pattern match
$node_(2) set Y_ 293.0222761518543
sed命令默认禁止打印(-n
),然后打印\$node_(2)
的第一个匹配项中的所有行(逃避$
这里不是绝对必要的,但总是一个好主意,如果您不要将它用作行尾锚点)到文件的末尾($
地址)。
cat
命令首先打印替换文件,然后输出sed命令的输出。
或使用sed r
("read") command (提示tripleee建议使用-e
):
$ sed -n -e '1r replace' -e '/\$node_(2)/,$p' infile
$node_(0) set X_ 10.0
$node_(0) set Y_ 10.0
$node_(1) set X_ 510.0
$node_(1) set Y_ 510.0
$node_(2) set X_ 270.0 //so basically here is the pattern match
$node_(2) set Y_ 293.0222761518543
这些命令被分成多个-e
块,因为r
对于它所看到的文件名有点挑剔。如果$node_(2)
出现在第一行,它就会中断,但如果是这种情况,你可以真正地连接你的文件。
答案 2 :(得分:1)
使用GNU sed:
sed '0,/$node_(2)/{//!d;s//text to add\n&/}' file
答案 3 :(得分:-1)
我建议采用多步骤流程。
首先,将您想要的行放在文件中,例如header.txt
。
现在,找到要删除的最后一行的行号:
$ first=$( grep -n '^\$node_(2)' test.txt | head -1 | cut -d: -f1 )
$ last=$(( first -1 ))
从文件中删除这些行:
$ sed "1,${first}d" myfile.txt
现在,将这两个文件放入临时文件并重命名临时文件:
$ cat header.txt myfile.txt > tmp$$ && mv tmp$$ myfile.txt