Please help. i'm struggling with a line printing one word before and one word after the match. ideally is to make number of words variable, but at lease 1 is needed.
sample Input
https://suttacentral.net/sn45.78-82 1 Saṁyutta Nikāya 45.78–82 8. Dutiyaekadhammapeyyālavagga Sīlasampadādisuttapañcaka
sn45.78-82 yathayidaṁ, bīṁāṅñhikkhave, chandasampadā …pe…
https://suttacentral.net/sn45.8 4 Saṁyutta Nikāya 45.8 1. Avijjāvagga Vibhaṅgasutta
sn45.8 Idha, bhikkhave, bhikkhu anuppannānaṁ pāpakānaṁ akusalānaṁ dhammānaṁ īṁāṅñanuppādāya chandaṁ janetīṁāṅñi vāyamati vīriyaṁ ārabhati cittaṁ paggaṇhāti padahati,
expected Output
bīṁāṅñhikkhave, chandasampadā …pe…
īṁāṅñanuppādāya chandaṁ janetīṁāṅñi
i don't know how to deal with symbols like **ī ṁ ā ṅ ñ ** etc
word related regexs don't handle these symbols properly
what i use
pattern=chand
grep -oP '(?:\s*\D?\s*){0,'10'}'"$pattern"'(?:\s*\D?\s*){0,'10'}'
what i get
ve, chandasampadā …pe…
▒ya chandaṁ janeti
please advice some solution. Grep, sed, awk, whatever available on default centos (can't install other utils)
CodePudding user response:
Assuming that, as in the example you provided, the target word only appears once per input line or is separated by at least 2*num words from other occurrences of it:
$ regexp=chand
$ num=1
$ grep -Eo "(\S \s ){,$num}\S*$regexp\S*(\s \S ){,$num}" file
bīṁāṅñhikkhave, chandasampadā …pe…
īṁāṅñanuppādāya chandaṁ janetīṁāṅñi
$ num=2
$ grep -Eo "(\S \s ){,$num}\S*$regexp\S*(\s \S ){,$num}" file
yathayidaṁ, bīṁāṅñhikkhave, chandasampadā …pe…
dhammānaṁ īṁāṅñanuppādāya chandaṁ janetīṁāṅñi vāyamati
The above uses GNU grep for -o
and \s/\S
and assumes you want to do regexp matching as you're doing in the question rather than string matching.
CodePudding user response:
Assumptions:
- words are delimited by white space
- there could be more than one match on a line (including overlaps) and if so each set of output is to be printed on a new line
Adding the following lines to the end of OP's input file:
$ tail -2 file
chand1 chand2 chand3 # multiple matches, overlaps, start/end of line matches
abc def ghi chand1 jkl mno chand2 pdq # multiple matches, overlaps
One awk
idea based on a hard-coded before/after count of 1
:
awk -v ptn='chand' '
{ for (i=1;i<=NF;i )
if ($i ~ ptn)
print (i>1 ? $(i-1) OFS : "") $i ($i<NF ? OFS $(i 1) : "")
}' file
This generates:
bīṁāṅñhikkhave, chandasampadā …pe…
īṁāṅñanuppādāya chandaṁ janetīṁāṅñi
chand1 chand2
chand1 chand2 chand3
chand2 chand3
ghi chand1 jkl
mno chand2 pdq
Expanding to handle a user-defined count of leading/trailing words:
awk -v ptn='chand' -v cnt1=1 -v cnt2=1 '
{ for (i=1;i<=NF;i )
if ($i ~ ptn) {
sep=""
for (j=i-cnt1;j<=i cnt2;j ) {
if (j<1 || j>NF) continue
printf "%s%s", sep ,$j
sep=OFS
}
print ""
}
}' file
For cnt1=1 / cnt2=1
this generates:
bīṁāṅñhikkhave, chandasampadā …pe…
īṁāṅñanuppādāya chandaṁ janetīṁāṅñi
chand1 chand2
chand1 chand2 chand3
chand2 chand3
ghi chand1 jkl
mno chand2 pdq
For cnt1=2 / cnt2=2
this generates:
yathayidaṁ, bīṁāṅñhikkhave, chandasampadā …pe…
dhammānaṁ īṁāṅñanuppādāya chandaṁ janetīṁāṅñi vāyamati
chand1 chand2 chand3
chand1 chand2 chand3
chand1 chand2 chand3
def ghi chand1 jkl mno
jkl mno chand2 pdq
For cnt1=1 / cnt2=2
this generates:
bīṁāṅñhikkhave, chandasampadā …pe…
īṁāṅñanuppādāya chandaṁ janetīṁāṅñi vāyamati
chand1 chand2 chand3
chand1 chand2 chand3
chand2 chand3
ghi chand1 jkl mno
mno chand2 pdq