AWK打印列中唯一值的最小最大值
AWK to print min max values of unique value in column
我正在尝试使用 awk 执行以下操作:
输入文件:
6:28866209 NA NA NA 8.51368e-06 Y
6:28856689 1 0.007828 1 1.50247e-06 X
6:28856740 2 0.007828 1 1.50247e-06 Y
6:28856889 3 7.51E-08 3 1.50247e-06 X
我想:
- 为第 6 列中的每个独立值获取第 5 列的最小值和最大值
- 在文件末尾为每列 5 打印文件中的最小最大值
文件可以有不同的 N 列,但都至少有 1-8 列,这在我的每个文件中都是相同的。
输出:
6:28866209 NA NA NA 8.51368e-06 Y 8.51368e-06 1.50247e-06
6:28856689 1 0.007828 1 1.50247e-06 X 1.50247e-061.50247e-06
6:28856740 2 0.007828 1 1.50247e-06 Y 8.51368e-06 1.50247e-06
6:28856889 3 7.51E-08 3 1.50247e-06 X 1.50247e-06 1.50247e-06
我尝试使用以下 awk 命令执行此操作,但我只取回第 6 列中的第一个值...
awk 'BEGIN{OFS="\t";FS="\t"}{if (a[] == "") a[]=; if (a[] > ) {a[]=}} {if (b[] == "") b[]=; if (b[] < ) {b[]=}} END {if (i=) print [=12=],i,a[i],b[i]}' FILE
我认为最简单的方法是使用文件的双重传递:
awk '(NR==FNR) && !( in min) { min[] = ; max[] = ; next }
(NR==FNR) { m=min[]; M=max[];
min[] = <m ? : m;
max[] = >M ? : M;
next; }
{print [=10=],min[],max[] }' <file> <file>
您的原始代码存在以下缺陷。 END
语句仅在到达文件末尾时执行。您尝试打印完整文件,但您没有在解析中存储任何行。
对您最初想法的更正是:
awk 'BEGIN{OFS="\t";FS="\t"}
{if (a[] == "") a[]=;
if (a[] > ) {a[]=}
}
{if (b[] == "") b[]=;
if (b[] < ) {b[]=}
}
{ c[NR]=[=11=]; d[NR]= }
END { for (i=1;i<=NR;i++) print c[i],a[d[i]],b[d[i]] }' FILE
在这里,我将完整的 FILE
存储在数组 c
中,该数组由 line-number NR
索引。我还将索引 </code> 存储在数组 <code>d
中。最后,我遍历存储的所有行并打印预期内容。
- 这种方法的缺点是您必须将整个文件存储在内存中。
- 我的建议的缺点是您必须从磁盘读取整个文件两次。
awk 'FNR<NR{=m[];=M[];print;next} (!M[])||>M[]{M[]=}(!m[])||<m[]{m[]=}' file file
有评论
awk '
# optional format
BEGIN { OFS=FS="\t"}
# for second pass (second file read)
FNR<NR{
# add a column 7 and 8 with value of min and max correponsing to column 5
=m[];=M[]
# print it and reda next line (don't go further in script)
print;next}
# this point is only reach by first file read
# if Max is unknow or value 5 bigger than max
(!M[])||>M[]{
# set new max
M[]=}
# do the same for min
(!m[])||<m[]{m[]=}
# read 2 times the same file (first to find min/max, second to print it)
' sample.txt sample.txt
我正在尝试使用 awk 执行以下操作:
输入文件:
6:28866209 NA NA NA 8.51368e-06 Y
6:28856689 1 0.007828 1 1.50247e-06 X
6:28856740 2 0.007828 1 1.50247e-06 Y
6:28856889 3 7.51E-08 3 1.50247e-06 X
我想:
- 为第 6 列中的每个独立值获取第 5 列的最小值和最大值
- 在文件末尾为每列 5 打印文件中的最小最大值
文件可以有不同的 N 列,但都至少有 1-8 列,这在我的每个文件中都是相同的。
输出:
6:28866209 NA NA NA 8.51368e-06 Y 8.51368e-06 1.50247e-06
6:28856689 1 0.007828 1 1.50247e-06 X 1.50247e-061.50247e-06
6:28856740 2 0.007828 1 1.50247e-06 Y 8.51368e-06 1.50247e-06
6:28856889 3 7.51E-08 3 1.50247e-06 X 1.50247e-06 1.50247e-06
我尝试使用以下 awk 命令执行此操作,但我只取回第 6 列中的第一个值...
awk 'BEGIN{OFS="\t";FS="\t"}{if (a[] == "") a[]=; if (a[] > ) {a[]=}} {if (b[] == "") b[]=; if (b[] < ) {b[]=}} END {if (i=) print [=12=],i,a[i],b[i]}' FILE
我认为最简单的方法是使用文件的双重传递:
awk '(NR==FNR) && !( in min) { min[] = ; max[] = ; next }
(NR==FNR) { m=min[]; M=max[];
min[] = <m ? : m;
max[] = >M ? : M;
next; }
{print [=10=],min[],max[] }' <file> <file>
您的原始代码存在以下缺陷。 END
语句仅在到达文件末尾时执行。您尝试打印完整文件,但您没有在解析中存储任何行。
对您最初想法的更正是:
awk 'BEGIN{OFS="\t";FS="\t"}
{if (a[] == "") a[]=;
if (a[] > ) {a[]=}
}
{if (b[] == "") b[]=;
if (b[] < ) {b[]=}
}
{ c[NR]=[=11=]; d[NR]= }
END { for (i=1;i<=NR;i++) print c[i],a[d[i]],b[d[i]] }' FILE
在这里,我将完整的 FILE
存储在数组 c
中,该数组由 line-number NR
索引。我还将索引 </code> 存储在数组 <code>d
中。最后,我遍历存储的所有行并打印预期内容。
- 这种方法的缺点是您必须将整个文件存储在内存中。
- 我的建议的缺点是您必须从磁盘读取整个文件两次。
awk 'FNR<NR{=m[];=M[];print;next} (!M[])||>M[]{M[]=}(!m[])||<m[]{m[]=}' file file
有评论
awk '
# optional format
BEGIN { OFS=FS="\t"}
# for second pass (second file read)
FNR<NR{
# add a column 7 and 8 with value of min and max correponsing to column 5
=m[];=M[]
# print it and reda next line (don't go further in script)
print;next}
# this point is only reach by first file read
# if Max is unknow or value 5 bigger than max
(!M[])||>M[]{
# set new max
M[]=}
# do the same for min
(!m[])||<m[]{m[]=}
# read 2 times the same file (first to find min/max, second to print it)
' sample.txt sample.txt