如何使用正则表达式匹配(bash脚本)将文件中的特定行移动到另一个地方?

时间:2012-05-08 13:50:41

标签: regex string bash

好的,文件内容:

asdasd0
**asdasd1**
asdasd2
asdasd3
asdasd4
**asdasd5**
asdasd6

我想在“^ asdasd1”RegEx匹配行之前移动“^ asdasd5”RegEx匹配行:

asdasd0
**asdasd5**
**asdasd1**
asdasd2
asdasd3
asdasd4
asdasd6

HOWTO?

由于

7 个答案:

答案 0 :(得分:2)

目前尚不清楚你的模式是什么 - 什么是不变的,什么是变化的。

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

答案 1 :(得分:2)

以下是使用ex

的方法
ex inputfile <<'EOF'
/^asdasd5
d
/^asdasd1
-
put
wq
EOF

同样的事情在一条线上:

printf '%s\n' '/^asdasd5' 'd' '/^asdasd1' '-' 'put' 'wq' | ex inputfile

答案 2 :(得分:1)

使用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

答案 3 :(得分:1)

这可能对您有用:

sed '/asdasd1/,/asdasd5/{/asdasd5/{G;b};/asdasd1/{h;d};H;d}' file

答案 4 :(得分:1)

由于这是面向行的,因此您不需要正则表达式。当您看到起始线时,开始捕捉线条。当您看到结束行,打印它,打印捕获的行,然后打印文件的其余部分:

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
'

答案 5 :(得分:0)

最简单的方法是简单的awk双遍算法:

awk '(NR==FNR) { if ($0 ~ /asdasd5/) t=$0; next }
     /asdasd5/ { next }
     /asdasd1/ { print t }
     1' file file

答案 6 :(得分:-1)

使用sed的命令'i'在模式之前插入。 见http://www.grymoire.com/Unix/Sed.html#uh-41