分页: 1 / 1

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

发表于 : 2011-01-09 23:54
lilydjwg
我有一个(很大的)文件,现需要删除其中匹配 pattern 的行以及其前后各一行,如何操作?

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

PS: grep 的 -C 和 -v 同时使用不行。。。

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

发表于 : 2011-01-10 0:48
astolia
如果不想逐行分析处理的话,用sed的=取得行号,再用d删除那三行

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

发表于 : 2011-01-10 12:44
eexpress
-C 和 -v 同时使用不行
oops 才发现。

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

发表于 : 2011-01-10 18:24
realfiona

代码: 全选

#!/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

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

发表于 : 2011-01-10 19:14
astolia
ls的没考虑连续两行都匹配pattern的情况

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

发表于 : 2011-01-10 19:18
realfiona
astolia 写了:ls的没考虑连续两行都匹配pattern的情况
:em06 好像是的

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

发表于 : 2011-01-10 21:27
lilydjwg
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 脚本还是高亮起来比较好看~

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

发表于 : 2011-01-10 22:07
realfiona
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那种写法有什么区别

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

发表于 : 2011-02-15 23:36
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

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

发表于 : 2011-02-19 20:04
lilydjwg
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
你这样可行是可行,不过效率不高啊,关键是得生成新文件。

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

发表于 : 2011-02-20 6:29
sk1418
再来个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