linux recursively grep-A<num> jusqu'à une chaîne




linux find text in files recursively (3)

en supposant que nous avons un fichier contenant les éléments suivants:

chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num
chapter 2 blah blah

et nous voulons grep ce fichier afin que nous prenions les lignes du chapter 1 blah blah à blah num (la ligne avant le chapitre suivant).

Les seules choses que nous savons sont

  1. la chaîne de chapter 1 blah blah
  2. quelque part après qu'il y a une autre ligne commençant par le chapter

une façon factice de le faire est

grep -A <num> -i "chapter 1" <file>

avec suffisamment <num> pour que tout le chapitre soit dedans.


sed -ne '/^chapter 1/,/^chapter/{/^chapter/d;p}' file

Vous pouvez également le faire via grep mais vous devez activer les paramètres Perl-regexp P et z .

$ grep -oPz '^chapter 1[\s\S]*?(?=\nchapter)' file
chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num

[\s\S]*? fera une correspondance non-gourmande de zéro ou plusieurs caractères jusqu'à ce que la ligne qui a le chapter chaîne au début soit atteinte.

De l' man grep

-z, --null-data           a data line ends in 0 byte, not newline
-P, --perl-regexp         PATTERN is a Perl regular expression
-o, --only-matching       show only the part of a line matching PATTERN

C'est facile à faire avec awk

awk '/chapter/ {f=0} /chapter 1/ {f=1} f' file
chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num

Il imprimera la ligne si le drapeau f est vrai.
Le chapter 1 et le chapter suivant changent le drapeau.

Vous pouvez utiliser range avec awk mais c'est moins flexible si vous avez d'autres choses à tester.

awk '/chapter 1/,/chapter [^1]/ {if (!/chapter [^1]/) print}' file
chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num




fileparsing