linux下使用shell删除多行内容

Use the shell to delete multiple lines of content under linux

Posted by cslqm on July 12, 2019

昨天遇到一个shell算法问题,需要删除一个文件中连续两行的内容。举个例子,比如删除相邻两行AAAA和BBBB。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
AAAA
BBBB  yes

AAAA

BBBB  yes


AAAA
# CCCC
BBBB  yes

AAAA
# CCCC

BBBB  yes

AAAA
   BBBB  yes

AAAA
BBBB  yes
CC
BBBB  #不能删除它

AAAA
hello
BBBB  no

AAAA和BBBB直接相邻符合要求;AAAA和BBBB之间有空白行符合要求;AAAA和BBBB之间只有注释行符合要求;AAAA和BBBB之间有注释行和空白行也符合要求;某一行前边有空格或者tab也符合要求;如果BBBB多次出现,不能删除到最后出现的BBBB。

目前的想到的方案就是:1.获取从AAAA开始到文件末尾的所有内容;2.将获取的内容清除掉,空白行注释行,和AAAA行;3.判断清除后剩余内容的第一行是否是BBBB;4.是,删除AAAA至BBBB。

那么用shell如何实现这个功能呢。上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function common::line_deletor() {
    common::log_function "common::line_deletor" "$*"
    local file=$1
    local line1=$2
    local line2=$3


    line_ret=$(grep -n "^$line1" "$file" 2>/dev/null | head -n 1 2>/dev/null | awk -F: '{print $1}' 2>/dev/null)
    sed -n "$line_ret,$ p" "$file" 2>/dev/null | grep -v "^$line1" 2>/dev/null | sed 's/^[ \t]*//g;s/[ \t]*$//g;/^$/d' 2>/dev/null | head -n 1 2>/d
ev/null | grep "$line2" 1>/dev/null 2>/dev/null
    if [ "$?" -eq 0 ]; then
        sed -i "/$line1/,/$line2/d" "$file"
    else
        if grep -i "^$line1" "$file" &>/dev/null; then
            sed -i "/^$line1.*/d" "$file"
        fi
    fi
}

1

1
grep -n "^$line1" "$file" 2>/dev/null | head -n 1 2>/dev/null | awk -F: '{print $1}' 2>/dev/null

将会获取line1第一次出现的行号line_ret。

2

1
sed -n "$line_ret,$ p" "$file"

将会获取从line1开始到文件末尾的所有内容。

3

1
grep -v "^$line1" 2>/dev/null | sed 's/^[ \t]*//g;s/[ \t]*$//g;/^$/d'

用来清除掉空白行,注释行以及line1行。

4

1
head -n 1 2>/dev/null | grep "$line2"

去第一行的内容判断是不是line2。

目前的实现方案就是这样,如果想到其他方案,会继续更新。