Рейтинг:-1

Как отфильтровать строки в файле csv с помощью bash на основе двух условий?

флаг br

Я делаю проект, в котором мне нужно разобрать файл csv (набор данных индийских пациентов с печенью) и я пытаюсь изменить положение одного столбца. Предпоследний столбец должен быть последним. Я следую этому подходу, но не знаю, правильный ли он:

в то время как IFS="," читать -r col1 col2 col9 col8 col

делать

эхо "$col1, $col2, $col9, $col8"

сделано < <(cut -d "," --fields=1,2,9,8 csvfile)

Также мне нужно разделить «мужской» и «женский» (col2) и просто показать те значения, где col9 = 3. Результат желания:

Женщины
38, Женский, 3, 5,6
38, Женский, 3, 5,6
32, Женский, 3, 6

и так далее

Мужчины
72, Мужской, 3, 7,4
60, Мужской, 3, 6,3
33, Мужской, 3, 5,4

и так далее

Как мне это сделать без использования grep или akw?

muru avatar
флаг us
Почему нельзя использовать grep или awk?
tucomax avatar
флаг br
Правила проекта. Я не могу это изменить.
muru avatar
флаг us
Какие правила проекта разрешают `cut`, но не `awk`?
Рейтинг:0
флаг cn

Я согласен с Муру, что отказ от наиболее подходящих инструментов не является оптимальным, хотя, вероятно, имеет свою цель. Я не думаю, что это возможно сделать в одном цикле, по крайней мере, без предварительной сортировки файла или удаления заголовка. С помощью ассоциативного массива можно имитировать «группировку», где ключ становится женским или мужским, а его поля «сериализуются» как значения. Во-первых петля _ используется для пропуска полей, а второй для петля перебирает ключи и форматирует вывод.

#!/бин/баш

объявить -A A=()
объявить -A B=([Мужчина]=Мужчины [Женщины]=Женщины)

в то время как IFS=, читать -r a b _ _ _ _ _ c d _ ; делать
    [[ $d = 3 ]] && \
        А[$b]+=" $а $b $d $с"
сделано < файл.csv

для e в ${!A[@]}; делать
    printf %s%s\n "$nl" ${B[$e]}
    printf '%s, %s, %s, %s\n' ${A[$e]}; пл=$'\n'
сделано
tucomax avatar
флаг br
В этом ответе есть все функции, которые я искал.Спасибо, я увидел свои ошибки.
Рейтинг:0
флаг cn

Я бы вставил оператор IF вокруг эха и добавил его в отдельные файлы.

Перед началом цикла чтения

# спокойно стираем файлы CSV
rm col2eq8.csv 2> /dev/null
rm col2noteq8.csv 2> /dev/null

Внутри вашего цикла чтения:

# если $col2 равно 8
если [[ "$col2" -eq 8 ]]
тогда
  # затем переупорядочить столбцы и добавить в файл col2eq8.csv
  echo "$col1, $col2, $col9, $col8" >> col2eq8.csv
еще
  # иначе изменить порядок столбцов и добавить их в col2noteq8.csv
  echo "$col1, $col2, $col9, $col8" >> col2noteq8.csv
фи

Измените две команды эха, чтобы получить только нужные поля в нужном вам порядке.

Если вам нужно разделить на основе столбцов, измените «$ col2 -eq 8» на любое условие, которое вы хотите.

Для других манипуляций с CSV только для bash см. Парсинг Bash CSV.

tucomax avatar
флаг br
Спасибо за ваш ответ. Дело в том, что я ошибся. Вместо col8 стоит col2. Кроме того, каждая строка в этом столбце является мужской или женской, и я должен разделить их и собрать всех мужчин вместе, и то же самое с женщинами. Наконец, мне нужно показать только строки, равные 3 из col9.
флаг cn
Вы можете изменить свои операторы IF, например. col2=мужчина и (&&) col9=3: if [[ "$col2" == "Мужчина" && "$col9" -eq 3 ]]
tucomax avatar
флаг br
Это тоже отличный ответ. Мне очень помогает справиться с задачей.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.