Bash метод удаления последних 4 столбцов из файла csv

Есть ли способ использовать bash для удаления последних четырех столбцов для некоторого входного CSV файла? Последние четыре столбца могут иметь поля, которые различаются по длине от линии к строке, поэтому недостаточно просто удалить определенное количество символов с конца каждой строки.

Ответ 1

Cut может сделать это, если все строки имеют одинаковое количество полей или awk, если вы этого не сделаете.

cut -d, -f1-6 # assuming 10 fields

Будет распечатываться первые 6 полей, если вы хотите контролировать использование выходного seperater --output-delimiter = string

awk -F , -v OFS=, '{ for (i=1;i<=NF-4;i++){ printf $i, }; printf "\n"}'

Перебирает поля до количества полей -4 и выводит их.

Ответ 2

cat data.csv | rev | cut -d, -f-5 | rev

rev меняет линии, поэтому не имеет значения, имеет ли все строки одинаковое количество столбцов, оно всегда будет удалять последние 4. Это работает только в том случае, если последние 4 столбца не содержат никаких запятых.

Ответ 3

Вы можете использовать cut для этого, если знаете количество столбцов. Например, если ваш файл имеет 9 столбцов, а запятая - ваш разделитель:

cut -d',' -f -5

Однако это предполагает, что данные в вашем файле csv не содержат никаких запятых. cut интерпретирует запятые внутри кавычек как разделители.

Ответ 4

awk -F, '{NF-=4; OFS=","; print}' file.csv

или, альтернативно,

awk -F, -vOFS=, '{NF-=4;print}' file.csv

удалит последние 4 столбца из каждой строки.

Ответ 5

awk one-liner:

awk -F, '{for(i=0;++i<=NF-5;)printf $i", ";print $(NF-4)}'  file.csv

преимущество использования awk over cut заключается в том, что вам не нужно подсчитывать, сколько столбцов у вас есть, и сколько столбцов вы хотите сохранить. Поскольку вы хотите удалить последние 4 столбца.

см. тест:

kent$  seq 40|xargs -n10|sed 's/ /, /g'           
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
11, 12, 13, 14, 15, 16, 17, 18, 19, 20
21, 22, 23, 24, 25, 26, 27, 28, 29, 30
31, 32, 33, 34, 35, 36, 37, 38, 39, 40

kent$  seq 40|xargs -n10|sed 's/ /, /g' |awk -F, '{for(i=0;++i<=NF-5;)printf $i", ";print $(NF-4)}'
1,  2,  3,  4,  5,  6
11,  12,  13,  14,  15,  16
21,  22,  23,  24,  25,  26
31,  32,  33,  34,  35,  36

Ответ 6

Это может сработать для вас (GNU sed):

sed -r 's/(,[^,]*){4}$//' file

Ответ 7

Это awk-решение взломанным способом

awk -F, 'OFS=","{for(i=NF; i>=NF-4; --i) {$i=""}}{gsub(",,,,,","",$0);print $0}' temp.txt

Ответ 8

Ни один из упомянутых методов не будет работать должным образом при наличии файлов CVS с полями в кавычках с символом <запятая>. Так что немного сложно использовать <comma> -character в качестве разделителя полей.

Следующие два поста теперь очень удобны:

Поскольку вы работаете с GNU awk, вы можете выполнить любое из следующих двух действий:

$ awk -v FPAT='[^,]*|"[^"]+"' -v OFS="," 'NF{NF-=4}1'

Или с любым awk, вы можете сделать:

$ awk 'BEGIN{ere="([^,]*|\042[^\042]+\042)"
             ere=","ere","ere","ere","ere"$"
       }
       {sub(ere,"")}1'