Имея файл следующего содержания:
1111,2222,3333,4444
aaaa,bbbb,cccc,dddd
Я стремлюсь получить файл, равный оригиналу, но в котором отсутствует n-й столбец, например, для n = 2 (или, может быть, 3)
1111,2222,4444
aaaa,bbbb,dddd
или, для n = 0 (или может быть 1)
2222,3333,4444
bbbb,cccc,dddd
Реальный файл может иметь размер в гигабайты и содержать десятки тысяч столбцов.
Как всегда в таких случаях, я подозреваю, что волшебники командной строки могут предложить элегантное решение... :-)
В моем реальном случае мне нужно удалить два первых столбца, что можно сделать, дважды удалив первый столбец подряд, но я полагаю, что было бы интереснее немного обобщить.
решение1
Я считаю, что это относится только к вырезанию из GNU coreutils:
$ cut --complement -f 3 -d, inputfile
1111,2222,4444
aaaa,bbbb,dddd
Обычно вы указываете нужные поля с помощью -f, но, добавляя --complement, вы, естественно, меняете значение на противоположное. Из 'man cut':
--complement
complement the set of selected bytes, characters or fields
Одно предостережение: если какой-либо из столбцов содержит запятую, он выдаст cut off, потому что cut не является парсером CSV в том смысле, в каком им является электронная таблица. У многих парсеров разные идеи о том, как обрабатывать экранированные запятые в CSV. Для простого случая CSV в командной строке cut по-прежнему остается правильным выбором.
решение2
Если данные просто состоят из столбцов, разделенных запятыми:
cut -d , -f 1-2,4-
Вы также можете использовать awk, но это немного неудобно, потому что, хотя очистка поля проста, удаление разделителя требует некоторой работы. Если у вас нет пустых полей, это не так уж и плохо:
awk -F , 'BEGIN {OFS=FS} {$3=""; sub(",,", ","); print}'
Если у вас есть настоящий CSV-файл, где запятые могут появляться внутри полей, если они правильно закавычены, вам нуженнастоящая библиотека CSV.
решение3
Использование инструмента с поддержкой CSV для удаления двух первых столбцов из входного CSV-файла без заголовка:
$ cat file
1111,2222,3333,4444
aaaa,bbbb,cccc,dddd
$ mlr --csv -N cut -x -f 1,2 file
3333,4444
cccc,dddd
Вариант -x
операции cut
вМиллер( mlr
) приводит к тому, что операцияисключатьименованные поля (в данном случае поля номер 1 и 2). Если бы данные CSV имели заголовки, мы бы могли использовать именованные поля с -f
( -N
опция также должна быть удалена в этом сценарии).
Поскольку Miller поддерживает CSV, он обрабатывает правильно заключенные в кавычки поля, содержащие встроенные запятые, кавычки и символы новой строки.
решение4
Попробуйте выполнить команду ниже, чтобы удалить столбцы с помощью индекса.
dropColumnCSV --index=0 --file=file.csv
Это сработает, если столбцы разделены запятой, как показано ниже.седДля удаления строк внутри функции используются команды.
dropColumnCSV() {
# argument check
while [ $# -gt 0 ]; do
case "$1" in
--index=*)
index="${1#*=}"
;;
--file=*)
file="${1#*=}"
;;
*)
printf "* Error: Invalid argument. *\n"
return
esac
shift
done
# file check
if [ ! -f $file ]; then
printf "* Error: $file not found.*\n"
return
fi
# sed remove command index zero
if [[ $index == 0 ]]; then
sed -i 's/\([^,]*\),\(.*\)/\2/' $file
# sed remove command index greater than zero
elif [[ $index > 0 ]]; then
pos_str=$(for i in {1..$(seq "$index")}; do echo -n '[^,]*',; done| sed 's/,$//') ;
sed -i 's/^\('$pos_str'\),[^,]*/\1/' $file
fi
}