8

I have a text file contaning the following:

"random
textA"
"random
random
textB"

The separator is "

How can I split the containt into multiple file as follow using a bash command?

File 1 :

random
textA

File 2 :

random
random
textB

I came into examples using csplit or awk but they does not cover this text layout.

2
  • Is that the only text in the file? Dec 8, 2014 at 17:15
  • yes only text in the file
    – Fabio
    Dec 9, 2014 at 9:38

4 Answers 4

7

Simple awk command:

awk 'NR%2==0{ print >("File " ++i) }' RS='"' infile

RS defines " as record separator and NR is the record number. If the record number was modulo of 2 (because we have another first " for records), then print the current record $0 into a File #.

4
  • 1
    This is IMO the best answer as it works even if other lines exist between "$ and the next ^". Dec 8, 2014 at 21:26
  • don't need the begin just use ++i instead of i++.Could be shortened to awk 'NR%2==0{ print >"File "++i }' RS='"' file
    – user78605
    Dec 8, 2014 at 22:33
  • @Jidder Uh,yes. thank you. updated with that, Dec 9, 2014 at 4:40
  • My goodness - spaces in file names? May you be forgiven.
    – cornuz
    Oct 24, 2023 at 9:48
5

If the opening quote is always at the beginning of the line, csplit will work just fine like this:

bash$ csplit /tmp/data '/^"/'

That produces files called xx00, etc. Note, your example removes the quotation marks and this doesn't. You'd need a command line sed to do that:

bash$ for file in xx* ; do { sed 's/^"//;s/"$//;' ${file} >x${file}; } ; done
1
  • With coreutils csplit: csplit -z filesample '/^"/' {*} so as to split more than once and ignore the first piece (xx00) which will always be empty (for the given text sample). Dec 8, 2014 at 18:20
3

With GNU awk

awk -v RS='"[[:space:]]*"' '
{sub(/^"|"[[:space:]]*$/, "");print > "output." ++n; close("output." n)}' file.txt
1
  • An alternative: awk -v RS='"' '!/^[[:space:]]*$/ {print > "output." n++; close...}'
    – muru
    Dec 8, 2014 at 17:49
2

You can do:

awk -v RS=\" -v ORS= \
  '{ sub(/^\n*/,"");sub(/\n*$/,""); };
  /^\n*$/ { next;};
  { if(strcnt==0) { print $0 >"file1"; strcnt++;} else
  { print $0 >"file2"; }; }' file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .