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.
Aia
July 7, 2015, 2:06pm
2
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}
RudiC
July 9, 2015, 2:52am
7
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
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
rudic:
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
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.