如何根据两个条件使用 bash 过滤 csv 文件中的行?

如何根据两个条件使用 bash 过滤 csv 文件中的行?

我正在做一个项目,需要解析一个 csv 文件(印度肝病患者数据集) 并且我试图改变一列的位置。倒数第二列必须是最后一列。我正在遵循这些方法,但我不知道这是否是正确的方法:

while IFS="," read -r col1 col2 col9 col8 col

do

echo "$col1, $col2, $col9, $col8"

done < <(cut -d "," --fields=1,2,9,8 csvfile)

另外,我需要区分“男性”和“女性”(col2),并且只显示 col9 = 3 的值。期望的输出是:

Women
38,Female,3, 5.6
38,Female,3, 5.6
32,Female,3, 6

等等

Men
72,Male,3, 7.4
60,Male,3, 6.3
33,Male,3, 5.4

等等

如果不使用 grep 或 akw 我该如何做到这一点?

答案1

我同意 Muru 的观点,不允许使用最适合的工具并不是最佳选择,但可能有其目的。我认为不可能在一个循环中做到这一点,至少在不先对文件进行排序或删除标题的情况下不可能。使用关联数组,可以模拟“分组依据”,其中键变为 Female 或 Male,其字段被“序列化”为值。在第一个环形 _用于跳过字段,第二个用于环形迭代所有键并格式化输出。

#!/bin/bash

declare -A A=()
declare -A B=([Male]=Men [Female]=Women)

while IFS=, read -r a b _ _ _ _ _ c d _ ; do
    [[ $d = 3 ]] && \
        A[$b]+=" $a $b $d $c"
done < file.csv

for e in ${!A[@]}; do
    printf %s%s\\n "$nl" ${B[$e]}
    printf '%s, %s, %s, %s\n' ${A[$e]}; nl=$'\n'
done

答案2

我会在 echo 周围粘贴一个 IF 语句并将其附加到单独的文件中。

在读取循环开始之前

# quietly erase CSV files
rm col2eq8.csv 2> /dev/null
rm col2noteq8.csv 2> /dev/null

在你的读取循环中:

# if $col2 equals 8
if [[ "$col2" -eq 8 ]]
then
  # then re-order columns and append to col2eq8.csv file
  echo "$col1, $col2, $col9, $col8" >> col2eq8.csv
else
  # else re-order columns and append to col2noteq8.csv
  echo "$col1, $col2, $col9, $col8" >> col2noteq8.csv
fi

更改两个 echo 命令以按照您想要的顺序获取您想要的字段。

如果需要根据列进行分隔,请将“$col2 -eq 8”更改为您想要的任何条件。

有关其他仅限 bash 的 CSV 操作,请参阅Bash CSV 解析

相关内容