Nicola Rocha
Nicola Rocha

Reputation: 15

Getting blocks of strings between specific characters in text file "bash"

can someone help me finding a code for copying all the strings between the string 'X 0' (X = H, He...) and the nearest '****'? I use bash for programming.

H 0
 S   3 1.00       0.000000000000
      0.1873113696D+02  0.3349460434D 01
      0.2825394365D+01  0.2347269535D+00
      0.6401216923D+00  0.8137573261D+00
 S   1 1.00       0.000000000000
      0.1612777588D+00  0.1000000000D+01
****
He 0
 S   3 1.00       0.000000000000
      0.3842163400D+02  0.4013973935D 01
      0.5778030000D+01  0.2612460970D+00
      0.1241774000D+01  0.7931846246D+00
 S   1 1.00       0.000000000000
      0.2979640000D+00  0.1000000000D+01
****

I want to do this for all the "X 0" (X = H, He...) especifically, obtaining a isolated text like that, for all the "X 0":

 H 0
 S   3 1.00       0.000000000000
      0.1873113696D+02  0.3349460434D 01
      0.2825394365D+01  0.2347269535D+00
      0.6401216923D+00  0.8137573261D+00
 S   1 1.00       0.000000000000
      0.1612777588D+00  0.1000000000D+01
****

and

 He 0
 S   3 1.00       0.000000000000
      0.3842163400D+02  0.4013973935D 01
      0.5778030000D+01  0.2612460970D+00
      0.1241774000D+01  0.7931846246D+00
 S   1 1.00       0.000000000000
      0.2979640000D+00  0.1000000000D+01
 ****

So I think I have to find a way to do it using the string containing "X 0". I was trying to use grep -A2000 'H 0' filename.txt | grep -B2000 -m8 '****' filename.txt >> filenameH.txt but its not so usefull for the other exemples of X, just for the first.

Upvotes: 0

Views: 135

Answers (2)

karakfa
karakfa

Reputation: 67537

if the records are separated with 4 stars. Needs gawk

$ awk -v RS='\\*\\*\\*\\*\n' '$1~/^He?$/{printf "%s", $0 RT > FILENAME $1}' file

this will only extract H and He records. If you don't want to restrict, just remove the condition before the curly brace. (Equivalent to $1=="H" || $1=="He")

Upvotes: 0

oliv
oliv

Reputation: 13259

Using awk:

awk '/^[^ ]+ 0$/{p=1;++c}/^\*\*\*\*$/{print >>FILENAME c;p=0}p{print >> FILENAME c}' file

The script creates as many files as there are blocks matching the the patterns /^[^ ]+ 0$/ and /^\*\*\*\*$/. The file index starts at 1.

Upvotes: 1

Related Questions