我需要有关执行以下操作的 bash 脚本的帮助:
| section | category | description | date | metric | value |
| --------| ---------|-------------|-----------|--------|----------|
| y | testing | abc |03/02/2022 | | 14845.0 |
| x | row | pqy | 01/16/2022| | 12565.0 |
| x | row | xyz | 02/21/2021| | 13888.0 |
| x | row | xyz | 10/04/2020| | 18160.0 |
当我搜索它的描述时,我想按降序返回值列以及日期,xyz
应该只返回与该值相对应的值,并且只返回与一个日期相关的最高值。也可能有重复的日期。例如:
10/04/2020 18160
02/21/2021 13888
在上面的例子中,我有描述,xyz
并且它返回按降序排列的值以及日期。
我尝试过的:我一直坚持这个
awk '$2 ~ /xyz/ {print $3}' covid19_cases_demographics_tests_2022-03-21.csv(this is my csv file)
请通过一些示例来指导我正确的方向,因为我是 shell 脚本和 unix 东西的新手。谢谢
答案1
根据您显示的列,您在中使用了错误的索引awk
看起来您假设第一列(部分)将是$0
,第二列(类别)将是$1
,第三列(描述)将是$2
。但awk
实际上用来$0
表示整条线。因此,要在描述列上搜索,您需要$3
在匹配逻辑中使用并$6
从值列中打印。假设您有正确的 csv 文件(不是其他格式),您可能还需要设置 -F 选项来指定自定义字段分隔符,例如逗号。但请注意,这有一个问题,即包含带引号的字符串的更复杂的 csv 文件可能仍然会破坏这个问题。
awk -F, '$3 ~ /xyz/ {print $6}' file.csv
如果您有更复杂的 csv 文件,其中引用的字符串可能包含空格甚至逗号等不用作分隔符的字符串,那么awk
(以及grep
和sed
) 可能不是完成这项工作的最佳工具。在这种情况下,该csvtool
实用程序是上下文感知的并且应该工作得更好。在 Fedora 上,该实用程序是软件包的一部分ocaml-csv
,但该软件包在其他发行版上的名称可能有所不同。
在这种情况下,您可以编写一个函数来打印所需的列,导出该函数,然后将csvtool
列传递给它。如果您有更复杂的字段,则需要更多工作,但更安全。
function printifcol {
local descCol="$3";
local valueCol="$6";
if [[ "xyz" == "${descCol}" ]]; then
echo "${valueCol}";
fi
}
export -f printifcol;
csvtool call printifcol file.csv
在任何一种情况下,您都可以使用(反向)选项将输出sort
通过管道传输到命令-r
,以按降序排列:
awk -F, '$3 ~ /xyz/ {print $6}' file.csv | sort -r
# assumes function was already exported
csvtool call printifcol file.csv | sort -r