Distribute lines to files based on character of first column (with awk)

Viewed 82

I have a file with tab-separated columns

AB01    1234
AB02    2342
CD01    dfde
CD02    3493
CD03    fdja
CDNC01  3343
Hans01  234r
Hans02  3jfe
HansNC01    jeff

I need to split this file into multiple files named after a part of the first column entry. In the new file the whole line should go in to. E.g. The first two lines should go into a file called AB.csv and so on.

This may clarify it:

AB01    1234 --> file: AB.csv
AB02    2342 --> file: AB.csv
CD01    dfde --> file: CD.csv
CD02    3493 --> file: CD.csv
CD03    fdja --> file: CD.csv
CDNC01  3343 --> file: CD.csv
Hans01  234r --> file: Hans.csv
Hans02  3jfe --> file: Hans.csv
HansNC01    jeff --> file: Hans.csv

It is usually everything until the number (two digits), but also if there is NC before the number.

Any help and hint is welcome.


EDIT

For the sake of completeness and to show my hopeless results:

awk 'BEGIN{FS=OFS="\t"}{ $1 ~ /(.+?)(NC|)\d\d/; \
    printf "%s\n", $0 >> <VARIABLE>".csv"}' \
    file.csv 

The first problem is getting a match for the first column. The second problem is getting the result as variable for the csv-file.

1 Answers

Could you please try following, written and tested with shown samples in GNU awk. This should help when lines are not sorted by 1st field.

awk '
{
  close(first)
  first=$1
  gsub(/[^a-zA-Z]*|NC/,"",first)
  print >> (first".csv")
}
' Input_file

Explanation: Adding detailed explanation of above.

awk '                              ##Starting awk program from here.
{
  close(first)                     ##Using close function with variable first value which is an output file name.
  first=$1                         ##Creating first with 1st field value here.
  gsub(/[^a-zA-Z]*|NC/,"",first)   ##Using gsub to substitute everything apart from alphabets OR NC with null in first variable.
  print >> (first".csv")           ##Printing current line into first.csv which is output file.
}
' Input_file                       ##Mentioning Input_file name here.


EDIT: As per OP comments if data is sorted by 1st field then one could try following.

awk '
{
  first=$1
  gsub(/[^a-zA-Z]*|NC/,"",first)
}
prev!=first".csv"{
  close(prev)
}
{
  print > (first".csv")
  prev=first".csv"
}
' Input_file
Related