Using Raku (née Perl_6), and/or Perl:
raku -pe 's:g/^^ <-[>]>  <-[.]>*?  <(\.)> /X/;'
OR (maybe more readable):
raku -pe 's:g{ ^^ <-[>]>  <-[.]>*?  <(\.)> } = Q{X};'
Raku is called at the shell command line with the -pe autoprint flags. The s/// in-place substitution operator is used here, in two guises. The first is the classic while the second is Raku's update to the Perl(5) s{...}{...}; idiom.
Briefly, reading the atoms left-to-right, "search starting from the ^^ start-of-line and where <-[>]> no ">" individual character is found, then where <-[.]>*? non-greedily no literal zero-or-more "." are found, if a <(\.)> literal "." is then found, drop all matches before/after and replace these "." with "X"; do this globally, linewise, autoprinting all lines with the substitution(s) as described."
Speaking of the Perl5 lineage, here's how you would do the P5 cognate to the second Raku example above (but the -pE command line flag might be better on older installs):
perl -pe 's{^ [^>]  [^.]*?  \K\. }{X}gx;'
(Special thanks to @Sinan Ünür for P5 guidance, link below).
https://stackoverflow.com/a/15578028/7270649
https://stackoverflow.com/a/24542792/7270649
https://docs.raku.org/language/operators#s///_in-place_substitution
https://raku.org/