@MaxMackie askubuntu.com/questions/88142/… . Я не могу получить мод там в этот час, поэтому я пометил его, попросив мигрировать, если они захотят; у него уже есть принятый ответ, так что я не уверен, будут ли они
Майкл Мрозек
@MichaelMrozek, хммм, что обычно происходит в этих ситуациях? Мы просто храним дубликаты?
Помимо того, как вырезать и переупорядочивать поля (описанные в других ответах), существует проблема необычных полей CSV.
Если ваши данные попадают в эту «причудливую» категорию, об этом может позаботиться небольшая часть предварительной и последующей фильтрации. Фильтры , указанные ниже , требуют символы \x01, \x02, \x03, \x04чтобы не появляться в любом месте в ваших данных.
Вот фильтры, обернутые вокруг простого awkдампа поля.
Примечание: field-Five имеет недопустимый / неполный макет «заключенного в кавычки», но он доброкачествен в конце строки (в зависимости от синтаксического анализатора CSV). Но, конечно, это приведет к проблематичным неисследованным результатам, если его поменять с текущей позиции в конце строки .
Обновить; user121196 указал на ошибку, когда запятая предшествует завершающей кавычке. Вот исправление.
Данные
cat <<'EOF'>file
field one,"fie,ld,two",field"three","field,\",four","field,five
"15111 N. Hayden Rd., Ste 160,",""
EOF
field one
"fie,ld,two"
field"three""field,\",four""field,five
"15111 N. Hayden Rd., Ste 160,"""
Вот предварительный фильтр , дополненный комментариями. Постфильтр только разворот . , , \x01\x02\x03\x04
sed -r '
s/^/,/# add a leading comma delimiter
s/\\"/\x01/g # obfuscate escaped quotation-mark (\")
s/,"([^"]*)"/,\x02\1\x03/g # obfuscate quotation-marks
s/,"/,\x02/# when no trailing quote on last field :MC # obfuscate commas embedded in quotes
s/\x02([^\x03]*),([^\x03]*)/\x02\1\x04\2/g
tMC
s/^,// # remove spurious leading delimiter'
Как бы вы удалили n-й столбец на основе этого фильтра?
user121196
@ user121196 - Как упомянуто в его первом предложении, этот ответ показывает способ сделать данные CSV более последовательными .. например. временно заменяя запятую, заключенную в кавычки, нейтральным символом токена ... и затем возвращая ее обратно в запятую после перемещения / вырезания / удаления. Опять же, как уже упоминалось, шаг перемещения / вырезания / удаления заменяется простым полевым дампом awk .
Peter.O
1
в данном случае это не так: «15111 N. Hayden Rd., Ste 160», «»
user121196
@ user121196: Спасибо, что указали на это. Я обновил ответ с исправлением.
Peter.O
15
Это зависит от того, использует ли ваш CSV-файл запятые только для разделителей, или если у вас есть сумасшествие, подобное:
поле одно, "поле, два", поле три
Это предполагает, что вы используете простой файл CSV:
Удаление столбца
Вы можете избавиться от одного столбца многими способами; Я использовал столбец 2 в качестве примера. Возможно, проще всего использовать этот метод cut, который позволяет вам указать разделитель -dи какие поля вы хотите напечатать -f; это говорит о том, что нужно разделить запятые и выходные поля 1 и поля 3 до конца:
$ cut -d,-f1,3-/path/to/your/file
Если вам действительно нужно использовать sed, вы можете написать регулярное выражение, которое совпадает с первыми n-1полями, nполем th и остальными, и пропустить вывод nth (здесь n2, поэтому первая группа соответствует 1time :) \{1\}:
$ sed 's/\(\([^,]\+,\)\{1\}\)[^,]\+,\(.*\)/\1\3/'/path/to/your/file
Есть несколько способов сделать это awk, но ни один из них не особенно элегантен. Вы можете использовать forцикл, но иметь дело с конечной запятой - боль; игнорируя, что это будет что-то вроде:
Так как это CSV, вам также понадобится BEGIN { FS=","; OFS=","; }.
1
Я думаю, что даже FS = OFS = "," будет работать.
5
Дан файл с разделителями пробелами в следующем формате:
12345
Вы можете удалить поле 2 с помощью awk следующим образом:
awk '{ sub($2,""); print}' file
который возвращается
1345
Замените столбец 2 на столбец n, где это необходимо.
Чтобы дублировать столбец 2,
awk '{ col = $2 " " $2; $2 = col; print }' file
который возвращается
122345
Чтобы переключить столбцы 2 и 3,
awk '{temp = $2; $2 = $3; $3 = temp; print}'
который возвращается
13245
Как правило, awk хорошо разбирается в понятии полей . Если вы имеете дело с CSV, а не с пробелом, вы можете просто использовать
awk -F,
чтобы определить ваше поле как запятую, а не пробел (который по умолчанию). В Интернете есть несколько хороших ресурсов awk, один из которых я перечислю в качестве источника ниже.
Я не очень разбираюсь в этом awk, но, похоже, он выводит разделенный пробелами, даже если разделитель полей (разделитель ,полей просто контролирует, как он обрабатывает ввод)
Майкл Мрозек
@MichaelMrozek: да, переменная OFS awk управляет разделителем выходного поля.
энзотиб
Да, и, как я упоминаю в своем ответе, вы можете передать опцию -F в awk, чтобы изменить разделитель (например, -F,)
Ответы:
Помимо того, как вырезать и переупорядочивать поля (описанные в других ответах), существует проблема необычных полей CSV.
Если ваши данные попадают в эту «причудливую» категорию, об этом может позаботиться небольшая часть предварительной и последующей фильтрации. Фильтры , указанные ниже , требуют символы
\x01
,\x02
,\x03
,\x04
чтобы не появляться в любом месте в ваших данных.Вот фильтры, обернутые вокруг простого
awk
дампа поля.Примечание: field-Five имеет недопустимый / неполный макет «заключенного в кавычки», но он доброкачествен в конце строки (в зависимости от синтаксического анализатора CSV). Но, конечно, это приведет к проблематичным неисследованным результатам, если его поменять с текущей позиции в конце строки .
Обновить; user121196 указал на ошибку, когда запятая предшествует завершающей кавычке. Вот исправление.
Данные
Код
Выход:
Вот предварительный фильтр , дополненный комментариями. Постфильтр только разворот . , ,
\x01
\x02
\x03
\x04
источник
Это зависит от того, использует ли ваш CSV-файл запятые только для разделителей, или если у вас есть сумасшествие, подобное:
Это предполагает, что вы используете простой файл CSV:
Удаление столбца
Вы можете избавиться от одного столбца многими способами; Я использовал столбец 2 в качестве примера. Возможно, проще всего использовать этот метод
cut
, который позволяет вам указать разделитель-d
и какие поля вы хотите напечатать-f
; это говорит о том, что нужно разделить запятые и выходные поля 1 и поля 3 до конца:Если вам действительно нужно использовать
sed
, вы можете написать регулярное выражение, которое совпадает с первымиn-1
полями,n
полем th и остальными, и пропустить выводn
th (здесьn
2, поэтому первая группа соответствует1
time :)\{1\}
:Есть несколько способов сделать это
awk
, но ни один из них не особенно элегантен. Вы можете использоватьfor
цикл, но иметь дело с конечной запятой - боль; игнорируя, что это будет что-то вроде:Мне легче вывести поле 1, а затем использовать,
substr
чтобы вывести все после поля 2:Это раздражает для колонок дальше, хотя
Дублирование столбца
В
sed
сущности это то же самое выражение, что и раньше, но вы также захватываете целевой столбец и включаете эту группу несколько раз в замену:В
awk
цикле for это будет что-то вроде (опять же игнорируя запятую):substr
Образом:(tcdyl предложил лучший метод в своем ответе )
Перемещение столбца
Я думаю, что
sed
решение естественно следует из других, но оно начинает смехотворно долгоисточник
awk
это ваша лучшая ставка.awk
печатает поля по номеру, так что ...Чтобы удалить столбец, не печатайте его:
Чтобы изменить порядок:
Перенаправить на выходной файл.
awk
Можно также отформатировать вывод.Вывод в формате Awk
источник
BEGIN { FS=","; OFS=","; }
.Дан файл с разделителями пробелами в следующем формате:
Вы можете удалить поле 2 с помощью awk следующим образом:
который возвращается
Замените столбец 2 на столбец n, где это необходимо.
Чтобы дублировать столбец 2,
который возвращается
Чтобы переключить столбцы 2 и 3,
который возвращается
Как правило, awk хорошо разбирается в понятии полей . Если вы имеете дело с CSV, а не с пробелом, вы можете просто использовать
чтобы определить ваше поле как запятую, а не пробел (который по умолчанию). В Интернете есть несколько хороших ресурсов awk, один из которых я перечислю в качестве источника ниже.
Источник для № 3
источник
awk
, но, похоже, он выводит разделенный пробелами, даже если разделитель полей (разделитель,
полей просто контролирует, как он обрабатывает ввод)Это будет работать для удаления
вход
Выход
источник