Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I would like to separate the following example text file into two separate files based on the embedded header record using a unix script:

CSI 447907 890947967201270
776666666   B
771555555   B
774444444   B
REL 447904 890947967201270
772222222   A
771111111   B+
770000000   A
CSI 447911 891096722201270
774444444   B+
778888888   A
779999999   A
REL 171077 889928722201270
774444444   B
773333333   B+
772222222   B+
771111111   C
PHY 114926 891987278201270
123456789   A
987654321   A
777777777   B+

The result files:

Text file 1

CSI 447907 890947967201270
776666666   B
771555555   B
774444444   B
CSI 447911 891096722201270
774444444   B+
778888888   A
779999999   A

Text file 2

REL 447904 890947967201270
772222222   A
771111111   B+
770000000   A
REL 171077 889928722201270
774444444   B
773333333   B+
772222222   B+
771111111   C
PHY 114926 891987278201270
123456789   A
987654321   A
777777777   B+

The number of header records can vary as well as the number of the detail records. The columns/fields are static. The first text file contains the CSI headers and corresponding detail records while the second is what is left over.

share|improve this question
    
This smells an awful lot like homework. if you want people to do your homework for you, at least format your question properly. –  Dennis Kaarsemaker Jan 28 '13 at 18:49
    
Steven, what have you tried so far? Where are you having difficulties? –  jaume Jan 28 '13 at 19:03
    
An answer is any scripting language (geared towards text munging), like Perl, Python, Ruby or others. –  vonbrand Jan 28 '13 at 22:12
add comment

2 Answers

Another typical job for awk:

POSIXLY_CORRECT=1 LC_ALL=C awk '
  $1 ~ /^[A-Z]{3}$/ {
    if ($1 == "CSI")
      file = "csi.txt"
    else
      file = "rest.txt"
  }
  file {print > file}'

POSIXLY_CORRECT is only in case your awk is GNU awk that doesn't recognize the {...} unless in standard conformant mode.

LC_ALL=C is to make sure [A-Z] means the ASCII character from A to Z, otherwise, that range might include other characters depending on the localisation settings.

If on Solaris, use command -p awk or /usr/xpg4/bin/awk as otherwise you might end up with /bin/awk which should not be used any longer.

share|improve this answer
add comment

I used a while loop and read down to the first CSI header. Then I was able to write the the header and detail records.

This is what I have thus far:

file="data.txt"
STR=CSI
while IFS= read -r line
do
    if [[ ${line} = @(${STR}*) ]] then
    echo $line > file2.txt
    while IFS= read -r line2
    do
      echo $line2 >> file2.txt
    done
    fi
done <"$file"

Steven

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.