Can I create 3 files in one command

Hi Gurus,

I need to separate a file to 3 (based on column 1 value). I have code like below. it works.

awk -F"|" '$1=="H" {print $0}' ${filename} > ${hea_name}
awk -F"|" '$1=="D" {print $0}' ${filename} > ${det_name}
awk -F"|" '$1=="T" {print $0}' ${filename} > ${tra_name}

is it possible to run awk once then create 3 files?

 
awk -F"|" '{if($1=="H") var="Hea"; else if ($1=="D") var="Det"; else var="Tra"; print $0, var}' file

I can get the value, but I don't know how to put the value in the output file name.

awk -F"|" -v head_name="$head_name" -v det_name="$det_name" -v tra_name="$tra_name"  '
    $1=="H" {print > head_name}
    $1=="D" {print > det_name}
    $1=="T" {print > tra_name}
' ${filename}

I would placed a next after every successful match, so it doesn't have to evaluate the $1 three times when it is already done with that line. Like:

$1=="H" {print > head_name; next}
1 Like

Or pretty similar to your attempt

awk -F"|" '{if($1=="H") var="Hea"; else if ($1=="D") var="Det"; else var="Tra"; print $0 > var}' file
1 Like

Assuming that the first field will always be exactly one of those three characters, you could also try something like:

awk -F'|' '{print > ($1=="D"?d:$1=="H"?h:t)}' d="$det_name" h="$hea_name" t="$tra_name" file
2 Likes

Thanks for all of you give me very good suggestion as always.

Somemore way

awk -F"|" -v head_name="$head_name" -v det_name="$det_name" -v tra_name="$tra_name" '
BEGIN{
	A["h"]=head_name
  	A["d"]=det_name
	A["T"]=tra_name
} 
$1 in A{
	print >A[$1]
	next
}' ${filename}

OR make a file which contains char to be matched and corresponding filename, something like this

[akshay@localhost tmp]$ cat search_list
h head_name
d det_name
T tra_name
a someother_name1
b someother_name2
c someother_name3 
awk '
FNR==NR{
	A[$1]=$2
	next
}
$1 in A{
	print >A[$1]
	next
}' search_list FS="|" ${filename}

As much as I appreciate this smart an compact solution, it has some minor drawbacks:

  • the leading single quote is missing for the script part
  • the "D" and "H" need double quote to become string constands else they're (empty) variables
  • ALL input lines not beginning with "D" or "H" will be stuffed into the tra_name file, which is not what was requested in post#1 (acknowledged that Don Cragun assumed only D, H, T)

Try this small adaption of Don Cragun's snippet:

awk -F'|' '{print > ($1=="D"?d:$1=="H"?h:$1=="T"?t:"/dev/null")}' d="det_name" h="hea_name" t="tra_name" file
1 Like

Thank you for catching my quoting problems. I should stop posting suggestions after my bedtime when I haven't made up reasonable test data when no test data was provided by the submitter. :o (They have been repaired in post #4.)

The assumption that all lines have "D", "H", or "T" as the value in field 1 comes from the submitter's 2nd code snippet in post #1. If there can be other values in the first field, your suggestion above handles that case very nicely.