2

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.

  • 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
3

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.

2

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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