2

Hi would like extract N number of lines after matching the first incidence of a string printing the N lines following using awk. The string is repeated a number of times in the file I am processing . I have tried using this command:

'c&&c--;/XCHT/{c=10}'

This prints all incidences of the match + 10 lines. I have seen various versions of this command after extensive searches but all versions produce largely the same result as below. I have looked around to find . I would like some tips on how to modify this command to achieve the result

The result of the match I would like to achieve is as follows

| XCHT            |    |
|-----------------|----|
| 柴胡chaihu      | 24 |
| 黄芩huangqin    | 9  |
| 法半夏banxia    | 12 |
| 生姜shengjiang  | 9  |
| 刺五加ciwujia   | 9  |
| 大枣dazao       | 6  |
| 炙甘草zhigancao | 9  |
|                 |    |
|                 |    |

A section of the file looks like this:

## XCHT
| XCHT            |    |
|-----------------|----|
| 柴胡chaihu      | 24 |
| 黄芩huangqin    | 9  |
| 法半夏banxia    | 12 |
| 生姜shengjiang  | 9  |
| 刺五加ciwujia   | 9  |
| 大枣dazao       | 6  |
| 炙甘草zhigancao | 9  |
|                 |    |
|                 |    |


## XCHT+CM

|                 |    |
|-----------------|----|
| 柴胡chaihu      | 24 |
| 黄芩huangqin    | 9  |
| 法半夏banxia    | 12 |
| 干姜ganjiang    | 9  |
| 五味子wuweizi   | 9  |
| 炙甘草zhigancao | 9  |
|                 |    |
|                 |    |

## XCHT+TM


| XCHT+TM                 |    |
|-----------------        |----|
| 柴胡chaihu              | 24 |
| 黄芩huangqin            | 9  |
| 法天花粉tianhuafen      | 12 |
| 生姜shengjiang          | 9  |
| 刺五加ciwujia           | 12 |
| 大枣dazao               | 6  |
| 炙甘草zhigancao         | 9  |
|                         |    |
|                         |    |
 

| XCHT-HQin+FL    |    |
|-----------------|----|
| 柴胡chaihu      | 24 |
| 黄茯苓fuling    | 12 |
| 法半夏banxia    | 12 |
| 生姜shengjiang  | 9  |
| 刺五加ciwujia   | 9  |
| 大枣dazao       | 6  |
| 炙甘草zhigancao | 9  |
|                 |    |
|                 |    |
## XCHT-DZ+ML

| XCHT-DZ+ML      |     |
|-----------------|-----|
| 柴胡chaihu      | 12  |
| 黄芩huangqin    | 4.5 |
| 法半夏banxia    | 6   |
| 生姜shengjiang  | 4.5 |
| 刺五加ciwujia   | 4.5 |
| 牡蛎 muli       | 6   |
| 炙甘草zhigancao | 4.5 |
|                 |     |
|                 |     |

The result of the command 'c&&c--;/XCHT/{c=10}' on the file

| XCHT            |    |
|-----------------|----|
| 柴胡chaihu      | 24 |
| 黄芩huangqin    | 9  |
| 法半夏banxia    | 12 |
| 生姜shengjiang  | 9  |
| 刺五加ciwujia   | 9  |
| 大枣dazao       | 6  |
| 炙甘草zhigancao | 9  |
|                 |    |
|                 |    |

| XCHT            |    |
|-----------------|----|
| 柴胡chaihu      | 24 |
| 黄芩huangqin    | 9  |
| 法半夏banxia    | 12 |
| 干姜ganjiang    | 9  |
| 五味子wuweizi   | 9  |
| 炙甘草zhigancao | 9  |
|                 |    |
|                 |    |



| XCHT+TM                 |    |
|-----------------        |----|
| 柴胡chaihu              | 24 |
| 黄芩huangqin            | 9  |
| 法天花粉tianhuafen      | 12 |
| 生姜shengjiang          | 9  |
| 刺五加ciwujia           | 12 |
| 大枣dazao               | 6  |
| 炙甘草zhigancao         | 9  |
|                         |    |
|                         |    |

| XCHT-DZ+ML      |     |
|-----------------|-----|
| 柴胡chaihu      | 12  |
| 黄芩huangqin    | 4.5 |
| 法半夏banxia    | 6   |
| 生姜shengjiang  | 4.5 |
| 刺五加ciwujia   | 4.5 |
| 牡蛎 muli       | 6   |
| 炙甘草zhigancao | 4.5 |
|                 |     |
|                 |     |

| Xiao Chaihi Tang -HQ+BS |    |
|-------------------------|----|
| 柴胡chaihu              | 24 |
| 白芍baishao             | 9  |
| 法半夏banxia            | 12 |
| 生姜shengjiang          | 9  |
| 刺五加ciwujia           | 9  |
| 大枣dazao               | 6  |
| 炙甘草zhigancao         | 9

The tables are a bit wonky as a result of copying them to the webpage. Any help of advice will be much appreciated .

4
  • Are the | part of the file or did you add them here only?
    – terdon
    Commented Feb 1, 2022 at 10:50
  • And does it need to be awk? If you have GNU grep you could just do grep -m1 -A10 XCHT.
    – terdon
    Commented Feb 1, 2022 at 10:53
  • the | are part of the file used as table separators
    – ajr_chm
    Commented Feb 1, 2022 at 20:57
  • Are those lines starting with ## really present above some blocks in your input, sometimes with a blank line after them, other times not?
    – Ed Morton
    Commented Feb 1, 2022 at 22:05

2 Answers 2

6

One way to handle this is to exit when c goes back to 0:

c { print; if (--c == 0) exit }; /XCHT/{c=10}

or more concisely,

c; c && !--c { exit }; /XCHT/{c=10}

GNU grep can do something similar:

grep -m1 -A10 XCHT

(but this will show the first line matching “XCHT” as well).

4
  • Thanks Stephen that did the trick . I had an idea that it might be something to do with exit but had no idea where to put it . I admit I only vaguely understand the use of c in an awk program . Do you have any tips for understanding it' usage, It does not seem to be well documented in any of the books or web resources I've come across.
    – ajr_chm
    Commented Feb 1, 2022 at 21:34
  • 1
    @ajr_chm c is just a variable, it could be named count or fluffy_bunny or anything else but c is a pretty common name for a counter variable. See printing-with-sed-or-awk-a-line-following-a-matching-pattern for more info on this and other awk idioms.
    – Ed Morton
    Commented Feb 1, 2022 at 22:35
  • Why is the c; present in the beginning of this command but not in any of the commands in the link . Something to do with the presence of exit ?
    – ajr_chm
    Commented Feb 2, 2022 at 7:10
  • 1
    @ajr_chm yes; in the linked examples, the conditions determine whether to print, but here there is one condition to print (c), and another to exit. c; is equivalent to c { print };, or more explicitly { if (c != 0) print }; (treating c as a purely numeric variable). Commented Feb 2, 2022 at 8:07
0

You seem to be trying to print a blank-line-separated record that just happens to be 10 lines long. Instead of counting lines and hard-coding how many lines you think are in a record, with awk you can just set RS to a null string to simply deal with such records no matter their length.

If those lines starting with ## aren't really present in your input then all you need is:

awk -v RS= '/XCHT/{print; exit}' file

otherwise if those lines really are present then we can remove them with a sub():

$ awk -v RS= '{sub(/##[^\n]*(\n|$)/,"")} /XCHT/{print; exit}' file
| XCHT            |    |
|-----------------|----|
| 柴胡chaihu      | 24 |
| 黄芩huangqin    | 9  |
| 法半夏banxia    | 12 |
| 生姜shengjiang  | 9  |
| 刺五加ciwujia   | 9  |
| 大枣dazao       | 6  |
| 炙甘草zhigancao | 9  |
|                 |    |
|                 |    |

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .