好的,文件内容:
asdasd0
**asdasd1**
asdasd2
asdasd3
asdasd4
**asdasd5**
asdasd6
我想在“^asdasd1”正则表达式匹配行之前移动“^asdasd5”正则表达式匹配行:
asdasd0
**asdasd5**
**asdasd1**
asdasd2
asdasd3
asdasd4
asdasd6
如何?
谢谢
目前尚不清楚您的模式是什么——什么是不变的,什么是变化的。
sed "/.*5/d;/.*1/i"$(sed -n '/.*5/p' FILE) FILE
我删除了包含 5 的行,并将该行插入到包含 1 的行后面。
您不能在此处使用 -i ,因为该文件是他自己的参考。
sed "/.*5/d;/.*1/i"$(sed -n '/.*5/p' FILE) FILE > FILE.tmp
mv FILE.tmp FILE
这是一种使用方法ex
:
ex inputfile <<'EOF'
/^asdasd5
d
/^asdasd1
-
put
wq
EOF
同样的事情都在一条线上:
printf '%s\n' '/^asdasd5' 'd' '/^asdasd1' '-' 'put' 'wq' | ex inputfile
一种使用方式perl
:
s/^(asdasd1.*)(^asdasd5(?:\n|$))/$2$1/sm
一个例子。内容script.pl
:
use warnings;
use strict;
my $data;
## Read all DATA content into $data variable.
do {
$/ = undef;
$data = <DATA>;
};
## Last 's' flag lets '.*' match newlines.
## 'm' flag lets '^' and '$' match at the beginning or end of each line.
$data =~ s/^(asdasd1.*)(^asdasd5(?:\n|$))/$2$1/sm;
print $data;
__DATA__
asdasd0
asdasd1
asdasd2
asdasd3
asdasd4
asdasd5
asdasd6
像这样运行它:
perl script.pl
具有以下输出:
asdasd0
asdasd5
asdasd1
asdasd2
asdasd3
asdasd4
asdasd6
这可能对您有用:
sed '/asdasd1/,/asdasd5/{/asdasd5/{G;b};/asdasd1/{h;d};H;d}' file
由于这是面向行的,因此您实际上并不需要正则表达式。当您看到起始线时,开始捕获这些线。当您看到结束行时,打印它,打印捕获的行,然后打印文件的其余部分:
awk -v start=asdasd1 -v end=asdasd5 '
match($0,start) {capture=1}
match($0,end) {print $0 captured; capture=0; next}
capture {captured = captured RS $0; next}
1
'
最简单的方法是一个简单的 awk 双通算法:
awk '(NR==FNR) { if ($0 ~ /asdasd5/) t=$0; next }
/asdasd5/ { next }
/asdasd1/ { print t }
1' file file
使用 sed 的命令 'i' 在模式之前插入。见http://www.grymoire.com/Unix/Sed.html#uh-41