0

I have a long text file, with some sections defined by these brackets on separate lines:

[EnvVarDefns]
[EnvVarDefns]    
[PROJECT]    
[EnvVarValues]

These lines occur only once, except for [EnvVarDefns] in the document, and it should be rather simple to select the text between them.

I want to save everything between the 2nd [EnvVarDefns] and [PROJECT] lines to one file, and finally everything from [EnvVarValues] to end of file to another file. After the selection, I do some data cleaning which I have verified works as intended. Only the first selection part is not working currently. I have this code:

for project in $projectlist
do

    sed -n 's/[EnvVarDefns]\(.*\)[PROJECT]/' file | sed /s/^/$project';'/ | sed 's/\\/;/g' | sed 's/;//9g' >> /params.csv;
    sed -n 's/^[EnvVarValues]/p' file | sed /s/^/$project';'/ | sed 's/\\/;/g' | sed 's/"//g' >> /values.csv;

done

This gives me the following errors:

sed: -e expression #1, char 31: unterminated `s' command
sed: -e expression #1, char 4: unknown command: `^'
sed: -e expression #1, char 19: unterminated `s' command

Any idea what is causing this?

UPDATE:

New code using awk:

for project in $projectlist
do

    awk '/\[EnvVarDefns]/ { found++ } found > 1 && printed <= 2 { print; printed++ }/{flag=1;next}/\[PROJECT]/{flag=0}flag' FILE |
    sed /s/^/$project';'/ | sed 's/\\/;/g' | sed 's/;//9g' >> /filepath/file1.csv;

    sed '1,/\[EnvVarValues]' FILE | sed /s/^/$project';'/ | sed 's/\\/;/g' | sed 's/"//g' >> /filepath/file2.csv;


done
bullfighter
  • 397
  • 1
  • 4
  • 21
  • Including the values in the `[..]` or only between? – Inian Jun 10 '20 at 11:32
  • `[EnvVarDefns]\(.*\)[PROJECT]` this will not work because by default `sed` works line by line (based on newline character) but you wish to match across multiple lines here.. also, `[` is a metacharacter, you need `\[` to match it literally – Sundeep Jun 10 '20 at 11:48
  • Preferably the values only between @Inian – bullfighter Jun 10 '20 at 12:14

1 Answers1

0

awk is better suited for such cases.

$ cat ip.txt
foo
blah blah
[EnvVarDefns]    
[PROJECT]    
[EnvVarValues]
abc 123
xyzas

# save the code in a file
$ cat code.awk
/\[EnvVarValues]/{f=0; n=1}
f{print > "f1.txt"}
/\[EnvVarDefns]/{f=1}
n{print > "f2.txt"}
# execute the program
$ awk -f code.awk ip.txt

$ cat f1.txt
[PROJECT]    
$ cat f2.txt
[EnvVarValues]
abc 123
xyzas

See also: How to print lines between two patterns, inclusive or exclusive (in sed, AWK or Perl)?

Sundeep
  • 23,246
  • 2
  • 28
  • 103
  • Thank you for your answer, it was of massive help! I did a mistake, I found that the first match occurs twice, which might have caused the errors. I updated OP with new code that takes this into account. – bullfighter Jun 10 '20 at 12:52