是这样的,我想用 sed 删除匹配到的行的指定范围行,比如 sed -i '/rows/d' data 是删除所有匹配到的包含 rows 字符串的行,但是在这些匹配行中,我想保留第一行,删除第 2 行到最后一行,有人知道怎么做吗?先谢谢了^ ^
1
lululau 2016-01-11 19:45:46 +08:00
sed -i '/rows/q'
|
3
xuboying 2016-01-11 19:54:11 +08:00 via Android
perl -ne 'if ($.>=2) {print unless /rows/} else {print}'
|
6
ficenow OP 补充一点,是影响匹配到的行,文件中的其他行不能动><
|
9
hucsmn 2016-01-11 20:09:14 +08:00
perl -e '$n=0; while(<>) {print if ($_ =~ /b/ && !($n++))}
|
10
hucsmn 2016-01-11 20:11:00 +08:00
上面写错= =, perl -e '$n=0; while(<>) {print if (!($_=~/rows/) || !($n++))}'
|
11
AnyOfYou 2016-01-11 20:11:21 +08:00
有个思路,可以先去替换第一行的 rows 到某个特殊的内容(只找第一个),然后再去删除包含 rows 的所有行,最后再把第一行的那个特殊关键字替换回 rows 。
|
17
ficenow OP @hucsmn tac|perl -e '$n=0; while(<>) {print if (!($_=~/rows/) || !($n++))}' data|tac > test
这样吗?会卡住 |
18
xuboying 2016-01-11 20:40:54 +08:00 via Android
perl -e '@x = <>; print $x[0];for (@x[1..$#x-1]){print unless /rows/ };print $x[$#x]}
|
20
ficenow OP @xuboying 把你那最后缺少的'补上也报错 syntax error at -e line 1, near "]}"
|
21
xuboying 2016-01-11 20:52:20 +08:00 via Android
哦,最后一花括号去掉换成单引号
|
23
xuboying 2016-01-11 20:58:37 +08:00 via Android
@ficenow 怎么可能, print $x[0] print $x[$#x] 是分别打印第一和最后一行
|
27
Earthman 2016-01-11 21:04:38 +08:00
第一行放暂存器,然后取出来,一行可以有多个 sed 命令,命令用 ; 分割
|
29
kingddc314 2016-01-11 21:10:52 +08:00
sed '2,$s/aaa/bbb/g' text
|
30
ficenow OP @kingddc314 你也理解错了,我的匹配行不在文件的第一行的
|
31
kingddc314 2016-01-11 21:14:53 +08:00
@ficenow 看错了,以为你是要从第二行开始替换,结果你是删除
|
32
lululau 2016-01-11 21:50:36 +08:00
sed -i '0,/rows/{//d}'
|
33
kingddc314 2016-01-11 21:56:11 +08:00
_rep() {
text=`sed -n '/$1/p' $2 | head -1` n=`sed -n '/$1/=' $2 | head -1` sed -i '/$1/d' $2 && sed -i "${n}i $text" $2 } _rep match a.txt # 鉴于楼主必须使用 sed ,可以先找出第一次匹配的内容和行号,然后删除后再把这一行给添加在之前的位置 # ps : osx 的 sed 和 linux 的差别很大!!! |
34
rrfeng 2016-01-11 22:01:27 +08:00 2
看到楼上都没有正确回答,闪开我要装逼了!
sed '1,/rows/!{/rows/d}' |
35
rrfeng 2016-01-11 22:02:44 +08:00
啊 32 楼已经给出来了……
逃 |
36
kingddc314 2016-01-11 22:07:14 +08:00 via Android
@rrfeng 可是楼主要的是保留第一次匹配的行,不是第一行
|
37
xuboying 2016-01-11 22:16:04 +08:00
|
38
rrfeng 2016-01-11 22:17:36 +08:00
@kingddc314 请自行测试
|
39
kingddc314 2016-01-11 22:27:29 +08:00
@rrfeng 我错了,你这确实是对的, good job
|
42
ficenow OP |
44
xuboying 2016-01-12 15:36:52 +08:00
perl -e '@x=<>;@i = grep { $x[$_]=~/rows/ } 0..$#x;$x[$i[$_]]="" for (1..$#i-1);print @x'
^----------改成$#i 就把最后一个干掉了 ^----------改成 0 就把第一个干掉了 |
45
xuboying 2016-01-12 15:37:31 +08:00
|
46
yingluck 2016-01-12 17:03:54 +08:00
awk '!/rows/{print} /rows/{if(a != 1){print;a=1}}'
|
48
lonelinsky 2016-01-12 19:39:52 +08:00 1
|
49
rrfeng 2016-01-12 22:53:16 +08:00
保留最后一行稍微换一下就好了啊
sed '/rows/,$!{/rows/d}' |
50
lonelinsky 2016-01-13 02:11:00 +08:00
@rrfeng 这个用来保留最后一个是不对的,你再看看…😂
|
51
ficenow OP @lonelinsky
@rrfeng rrfeng 那样不能保留最后一行, lonelinsky 的偷巧方法可以,但是 tac 命令处理文件的时候会把我文件的有些行合并(我也不知道怎么回事),所以把 tac 命令改为 sed '1!G;h;$!d'或 sed -n '1!G;h;$p'是可以的,但是处理速度不理想~~ |
52
lonelinsky 2016-01-14 09:52:28 +08:00
@ficenow 还可以试试这样 sed "`grep -n rows file | tail -1 | cut -d: -f1`! {/rows/d}" file
至于 tac 会合并的问题我这边没碰到,你试下把会合并的行摘出来看看? 或者用 vim -b 之类看下是不是不换行的地方有问题… |