删除文件中的匹配行及其附近的行

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
lilydjwg
论坛版主
帖子: 4165
注册时间: 2009-04-11 23:46
系统: Arch Linux
送出感谢: 11 次
接收感谢: 127 次
联系:

删除文件中的匹配行及其附近的行

#1

帖子 lilydjwg » 2011-01-09 23:54

我有一个(很大的)文件,现需要删除其中匹配 pattern 的行以及其前后各一行,如何操作?

又,我只需要删除第一次匹配 pattern 的行以及其前后各一行,又该如何做?

PS: grep 的 -C 和 -v 同时使用不行。。。
头像
astolia
论坛版主
帖子: 3107
注册时间: 2008-09-18 13:11
送出感谢: 1 次
接收感谢: 512 次

Re: 删除文件中的匹配行及其附近的行

#2

帖子 astolia » 2011-01-10 0:48

如果不想逐行分析处理的话,用sed的=取得行号,再用d删除那三行
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

Re: 删除文件中的匹配行及其附近的行

#3

帖子 eexpress » 2011-01-10 12:44

-C 和 -v 同时使用不行
oops 才发现。
● 鸣学
头像
realfiona
帖子: 137
注册时间: 2007-11-20 10:58
来自: Hangzhou, China
送出感谢: 0
接收感谢: 0
联系:

Re: 删除文件中的匹配行及其附近的行

#4

帖子 realfiona » 2011-01-10 18:24

代码: 全选

#!/bin/bash

if [ "$1" == "-g" ]; then
    GLOBAL=1 
    shift
fi

pat=$1
fname=$2

for i in $(sed -n -e "/$pat/=" $fname); do
    start=$(expr $i - 1)
    if [ -z $cmd ]; then
        cmd="$start,+2d"
        [ "$GLOBAL" != "1" ] && break
    else 
        cmd="$cmd;$start,+2d"
    fi
done

sed -e "$cmd" $fname
头像
astolia
论坛版主
帖子: 3107
注册时间: 2008-09-18 13:11
送出感谢: 1 次
接收感谢: 512 次

Re: 删除文件中的匹配行及其附近的行

#5

帖子 astolia » 2011-01-10 19:14

ls的没考虑连续两行都匹配pattern的情况
上次由 astolia 在 2011-01-10 19:19,总共编辑 2 次。
头像
realfiona
帖子: 137
注册时间: 2007-11-20 10:58
来自: Hangzhou, China
送出感谢: 0
接收感谢: 0
联系:

Re: 删除文件中的匹配行及其附近的行

#6

帖子 realfiona » 2011-01-10 19:18

astolia 写了:ls的没考虑连续两行都匹配pattern的情况
:em06 好像是的
头像
lilydjwg
论坛版主
帖子: 4165
注册时间: 2009-04-11 23:46
系统: Arch Linux
送出感谢: 11 次
接收感谢: 127 次
联系:

Re: 删除文件中的匹配行及其附近的行

#7

帖子 lilydjwg » 2011-01-10 21:27

realfiona 写了:[bash]
#!/bin/bash

if [ "$1" == "-g" ]; then
GLOBAL=1
shift
fi

pat=$1
fname=$2

for i in $(sed -n -e "/$pat/=" $fname); do
start=$(expr $i - 1)
if [ -z $cmd ]; then
cmd="$start,+2d"
[ "$GLOBAL" != "1" ] && break
else
cmd="$cmd;$start,+2d"
fi
done

sed -e "$cmd" $fname
[/bash]
学习了。以后去 prince 生成的图标不需要等 Vim 慢慢打开它再慢慢地保存了 :-)

PS: bash 脚本还是高亮起来比较好看~
头像
realfiona
帖子: 137
注册时间: 2007-11-20 10:58
来自: Hangzhou, China
送出感谢: 0
接收感谢: 0
联系:

Re: 删除文件中的匹配行及其附近的行

#8

帖子 realfiona » 2011-01-10 22:07

astolia 写了:ls的没考虑连续两行都匹配pattern的情况
[bash]
#!/bin/bash

if [ "$1" == "-g" ]; then
GLOBAL=1
shift
fi

pat=$1
fname=$2

start=0
for i in $(sed -n -e "/$pat/=" $fname); do
beg=$(expr $i - 1)
end=$(expr $i + 1)

if [ -z $cmd ]; then
cmd="${beg},${end}d"
[ "$GLOBAL" != "1" ] && break
else
cmd="${cmd};${beg},${end}d"
fi
done

echo $cmd
sed -e "$cmd" $fname
[/bash]

奇怪,直接用行号好像就没问题,不知道和+N那种写法有什么区别
sk1418
帖子: 229
注册时间: 2007-07-01 17:36
系统: (En):System
来自: (En):address
送出感谢: 2 次
接收感谢: 3 次
联系:

Re: 删除文件中的匹配行及其附近的行

#9

帖子 sk1418 » 2011-02-15 23:36

这个问题如果这样解决可行么?
假设文件叫sample.txt
假设LZ要的pattern是 "foo"

代码: 全选

grep -B1 -A1 "foo" sample.txt|grep -v -f - sample.txt

或者

grep -B1 -A1 "foo" sample.txt|comm -13 - sample.txt
---
regards,

Kent
头像
lilydjwg
论坛版主
帖子: 4165
注册时间: 2009-04-11 23:46
系统: Arch Linux
送出感谢: 11 次
接收感谢: 127 次
联系:

Re: 删除文件中的匹配行及其附近的行

#10

帖子 lilydjwg » 2011-02-19 20:04

sk1418 写了:这个问题如果这样解决可行么?
假设文件叫sample.txt
假设LZ要的pattern是 "foo"

代码: 全选

grep -B1 -A1 "foo" sample.txt|grep -v -f - sample.txt

或者

grep -B1 -A1 "foo" sample.txt|comm -13 - sample.txt
你这样可行是可行,不过效率不高啊,关键是得生成新文件。
sk1418
帖子: 229
注册时间: 2007-07-01 17:36
系统: (En):System
来自: (En):address
送出感谢: 2 次
接收感谢: 3 次
联系:

Re: 删除文件中的匹配行及其附近的行

#11

帖子 sk1418 » 2011-02-20 6:29

再来个sed的,不生成文件的。

代码: 全选

ArchT60::/tmp
kent$ cat sample.txt                                                  [ 23:19 ]
xxxx x xxx x x
xxx xx foo xx
xxxyy foo xx
ffd yyyy
zzz foo zzaz
bbb zzz xxx
==xxxxxxxxxx
xxxxxxxxxx
xxxfoo yyyyz
bolablablabla
==me too

如果pattern是foo
这个文件最终结果是就剩两行等号开头的吧?

kent$  sed -nr '/foo/!{h;N;/foo/D;};p' sample.txt |sed -nr '/foo/{n;/foo/!d;};p'|sed -nr '/foo/d;p'
==xxxxxxxxxx
==me too
要是不想用管道,也可以这样

代码: 全选

ArchT60::/tmp
kent$  sed -ir '/foo/!{h;N;/foo/D;}' sample.txt                       [ 23:27 ]
ArchT60::/tmp
kent$ sed -ir '/foo/{n;/foo/!d;}' sample.txt                          [ 23:27 ]
ArchT60::/tmp
kent$ sed -ir '/foo/d' sample.txt                                     [ 23:28 ]
ArchT60::/tmp
kent$ cat sample.txt                                                  [ 23:28 ]
==xxxxxxxxxx
==me too
---
regards,

Kent
回复

回到 “Shell脚本”