使用bash读取文本文件中的行的子集

时间:2009-07-05 07:04:21

标签: bash

我有一个文件

line a - this is line a
line b - this is line b
line c - this is line c
line d - this is line d
line e - this is line e

问题是:如何使用bash命令输出从“line b”开始到“line d”的行? 我的意思是,获得:

"line b - this is line b
 line c - this is line c
 line d - this is line d"

6 个答案:

答案 0 :(得分:5)

sed -n '/line b/,/line d/p' file

答案 1 :(得分:3)

用于您的示例数据集:

awk '/line b/,/line d/' file

awk '/line d/{f=0;print}/line b/{f=1}f' file

答案 2 :(得分:2)

如果用bash,你的意思是真的单独打击,我无法帮助你。你真的应该使用正确的工具来完成工作。如果您指的是可以从bash调用的标准UNIX实用程序,那么我将使用awk

echo 'line a - this is line a
line b - this is line b
line c - this is line c
line d - this is line d
line e - this is line e' | awk '
    BEGIN {e=0}
    /^line b/ {e=1}
    /^line d/ {if (e==1) {print;exit}}
    {if (e==1) print}
'

输出:

line b - this is line b
line c - this is line c
line d - this is line d

它的工作方式很简单。

  • e是echo标志,最初设置为false(0)。
  • 当你找到第b行时,将echo设置为true(1) - 不要打印。这将由下面的最后一个要点来处理。
  • 当您找到第d行并且回显打开时,打印并退出。
  • 当回显打开时,打印该行(包括第b行)。

我在这里做了一个假设,除非你已经回应,否则你不想在第d行退出。如果这是错误的,请将出口移到行d的if语句之外:

    /^line d/ {if (e==1) print;exit}

然后,如果你在你的第b行之前得到一行,它就会退出而不回应任何东西。

"/^line X/" - 类型的子句可以非常强大,可以很好地匹配你可以抛出的任何东西。

答案 3 :(得分:2)

您的示例不足以在一般情况下推断出您想要的内容,但假设您要删除第一行和最后一行,则可以使用

tail -n+2 $filename | head -n-1

此处tail -n+2打印从第二行开始的所有行,head -n-1打印除最后一行之外的所有行。

答案 4 :(得分:1)

你可以单独使用bash,虽然我同意Pax认为使用其他工具可能是更好的解决方案。这是一个仅限bash的解决方案:

while read line
do
    t=${line#line b}
    if test "$t" != "$line"
    then
        echo $line
        while read line
        do
            echo $line
            t=${line#line d}
            if test "$t" != "$line"
            then
                exit 0
            fi
        done
    fi
done

答案 5 :(得分:0)

另一种方法取决于你的意思:

pcregrep -m 'line b - this is line b
 line c - this is line c
 line d - this is line d' file