Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash:基于另一列的值获取一列的值_Bash_Sorting_Awk_Unix Head - Fatal编程技术网

Bash:基于另一列的值获取一列的值

Bash:基于另一列的值获取一列的值,bash,sorting,awk,unix-head,Bash,Sorting,Awk,Unix Head,我有一个以空间分隔的文件,其中包含: 5.75e-01 7.00e-1 5.52e-01 7.33e-01 ./dir1/dir2/file1.csv 5.75e-01 7.00e-1 5.42e-01 7.34e-01 ./dir1/dir2/file2.csv 5.75e-01 7.00e-1 5.72e-01 7.43e-01 ./dir2/dir2/file1.csv 5.75e-01 7.00e-1 5.22e-01 7.23e-01 ./dir2/dir2/file2.csv 5.7

我有一个以空间分隔的文件,其中包含:

5.75e-01 7.00e-1 5.52e-01 7.33e-01 ./dir1/dir2/file1.csv
5.75e-01 7.00e-1 5.42e-01 7.34e-01 ./dir1/dir2/file2.csv
5.75e-01 7.00e-1 5.72e-01 7.43e-01 ./dir2/dir2/file1.csv
5.75e-01 7.00e-1 5.22e-01 7.23e-01 ./dir2/dir2/file2.csv
5.75e-01 7.00e-1 5.02e-01 7.93e-01 ./dir3/dir2/file1.csv
5.75e-01 7.00e-1 5.12e-01 7.63e-01 ./dir3/dir2/file2.csv
我想提取第5列的值,该值对应于第3列中dir#的每个值的最大值。例如,假设我说的是
dir1
。对应于这些行的:

5.75e-01 7.00e-1 5.52e-01 7.33e-01 ./dir1/dir2/file1.csv
5.75e-01 7.00e-1 5.42e-01 7.34e-01 ./dir1/dir2/file2.csv
我可以通过以下方式找到这些:

max_val_acc_=$(awk '$5 ~ /dir1/ { print }' filename.txt)
echo $max_val_acc
现在我想我需要将这个结果通过
排序
,然后取
,但我无法让它工作。我要寻找的结果(对于
dir1
)是:

/dir1/dir2/file1.csv

以及所有dir#的完整结果:


我不确定我是否正确理解你,但这就是我理解你的方式:

awk -v s="dir1" '         # search parameter in your s
index($5,"./" s "/") {    # if your s is found in $5
    if(max==""||$3>max){  # we initialize $3 or compare to previous max
        max=$3;           # store new max
        maxv=$5           # and new mac value 
    }
}
END{ print maxv }         # print the stored max value
' file                    # oh just the file
./dir1/dir2/file1.csv

这就是你要找的吗

$ cat tst.awk
{
    split($5,path,"/")
    dir = path[2]
    if ( !(dir in max) || ($3 > max[dir]) ) {
        max[dir] = $3
        val[dir] = $5
    }
}
END {
    for (dir in val) {
        print val[dir]
    }
}

$ awk -f tst.awk file
./dir3/dir2/file2.csv
./dir1/dir2/file1.csv
./dir2/dir2/file1.csv

另一种选择是
sort
awk

$ sort -k5 -k3,3r file | awk -F/ '!a[$NF]++'

5.75e-01 7.00e-1 5.52e-01 7.33e-01 ./dir1/dir2/file1.csv
5.75e-01 7.00e-1 5.42e-01 7.34e-01 ./dir1/dir2/file2.csv
以上是文件名,如果基于第一个目录名

$ sort -k3,3r file | awk '{split($NF,d,"/")} !a[d[2]]++'

5.75e-01 7.00e-1 5.72e-01 7.43e-01 ./dir2/dir2/file1.csv
5.75e-01 7.00e-1 5.52e-01 7.33e-01 ./dir1/dir2/file1.csv
5.75e-01 7.00e-1 5.12e-01 7.63e-01 ./dir3/dir2/file2.csv
如果你只想打印目录

$ sort -k3,3r file | awk '{split($NF,d,"/")} !a[d[2]]++{print $NF}'

./dir2/dir2/file1.csv
./dir1/dir2/file1.csv
./dir3/dir2/file2.csv

只是为了好玩-没有任何(
awk
perl
之类)编程语言

file="./data.txt"
paste -d ' ' "$file" <(cut -d/ -f2 "$file") |\
    LC_ALL=C sort -k6 -k3gr | uniq -f5 | cut -d' ' -f5

使用一些awk解决方案。正如我所说,这只是为了显示另一种方式。

虽然与您请求的输出不匹配,并且与已经发布的其他答案类似,但我发现这个awk命令更令人难忘:

< file | sort -k3,3r | awk -F "/" '!seen[$2]++'
更一般的一点是:按大小对整个列表进行排序(第3列),不必担心按目录名对其进行排序(第5列的一部分),然后提取每个目录名的第一个(即,awk只打印新看到的键名)

如果确实希望仅输出目录名称和排序,请将以下内容添加到管道链:

| cut -d ' ' -f5- | sort

在进行最小/最大比较时,始终使用读取的第一个值作为种子,而不是希望所有输入值都为正值。另外,用
s=“dir2”
试试,你会看到它失败了,因为
dir2
出现在每一行上(你需要将它设为
索引($0,“./“s”/”)
或类似的值)。如果两个dir具有相同的max$3值,那么输出应该是什么?3r做什么?我理解-k3是按第3列排序的,但我阅读了排序手册页,仍然不理解-k3,3r
< file | sort -k3,3r | awk -F "/" '!seen[$2]++'
5.75e-01 7.00e-1 5.72e-01 7.43e-01 ./dir2/dir2/file1.csv
5.75e-01 7.00e-1 5.52e-01 7.33e-01 ./dir1/dir2/file1.csv
5.75e-01 7.00e-1 5.12e-01 7.63e-01 ./dir3/dir2/file2.csv
| cut -d ' ' -f5- | sort