Удаление возврата каретки с помощью sed

Вопрос или проблема

У меня есть большой файл CSV. В одном из полей содержится ошибка. Эта ошибка отображается как новая строка в файле.

До сих пор я использовал Notepad++ с этой командой для исправления проблемы:

\r”;” => “;”

Как я могу сделать то же самое с помощью sed?

Я уже пробовал

sed -i 's/\r";"https://unix.stackexchange.com/";"/g' /path/file.csv
sed -i 's/^";"https://unix.stackexchange.com/";"/g' /path/file.csv

безуспешно, возможно, кто-то здесь знает правильную команду.

Важно понимать, что sed работает построчно. Что делает sed, это в основном: читает строку в свой буфер без новой строки, выполняет ваши команды на буфере, печатает буфер (если вы не указали флаг -n), читает следующую строку в свой буфер и т.д. Поэтому, чтобы объединить две строки с помощью sed, требуется явно заставить sed обрабатывать больше одной строки за раз. Для этого команды N, P и D будут вам полезны.

Теперь по вашему конкретному вопросу, чтобы дать вам конкретный и протестированный ответ, мне нужно будет четко понимать вводимые данные, но вот несколько примеров того, что можно сделать :

Это объединит каждые две строки вместе :

sed $'N;s/[\\n\r]//g'

или, если вы уверены, что у вас всегда есть окончания строк \r\n :

sed 'N;s/.\n//'

Для более адаптированного решения к тому, что я понял из вашего вопроса, хотя это не лучший вариант, это должно сработать, если вы используете bash или другую оболочку, которая поддерживает C-экранирование через конструкцию $'str' :

sed $':l;N;/\r\\n";"/{;s/\r\\n";"https://unix.stackexchange.com/";"/g;n;};bl'

или без конструкции C-стиля и с окончаниями строк \r\n (неговорящее) :

sed ':l;N;/\n";"/{;s/.\n";"https://unix.stackexchange.com/";"/g;n;};bl'

Что оно делает, так это добавляет следующую строку в свой буфер (N) и проверяет на наличие нужной строки (/\r\\n";"/). Скрипт выполняет цикл (bl –> переход к метке :l, определенной в начале) до тех пор, пока не будет найдено совпадение. Когда совпадение найдено, выполняется скрипт sed между фигурными скобками: заменяются все вхождения \r\\n";" на ";" (s/\r\\n";"https://unix.stackexchange.com/";"/g) и очищается буфер, после чего вводится следующая строка (n).

Конечно, если файл большой и “ошибки” встречаются редко, это может занять много времени и потреблять много памяти. Если это так, можно использовать другой алгоритм, но мне нужно лучше понять вашу проблему, чтобы быть уверенным, что я правильно её понял.

Также, если вы хотите узнать немного больше о sed, я настоятельно рекомендую этот сайт, который, возможно, не имеет лучшего фона, но является лучшим туториалом по sed на данный момент.

Если вы хотите удалить символы \r, проще использовать фильтр tr:

cat file.csv | tr -d '\r' >newfile.csv

или напрямую:

tr -d '\r' <file.csv >newfile.csv

man tr будет вам полезен. Предупреждение: tr предназначен для использования как фильтр, читающий из его стандартного ввода, и он не может обрабатывать файл на месте, как sed -i.

Если вас устраивает решение на Perl:

perl -pe 's/\r";"https://unix.stackexchange.com/";"/g' foo.csv >foo_r.csv

У меня была подобная проблема, но я в итоге использовал немного другой вариант ответа @Fjor.

cat file.csv | tr -d '\n'.

(Tr – это TRanslate, который обычно является командой поиска/замены, но с -d просто удалит все вхождения строки поиска в одинарных кавычках.)

Я бы предложил это как комментарий к ответу Fjor, если бы у меня была репутация. Ну что ж, вот это так или иначе.

Ответ или решение

Чтобы удалить символы возврата каретки (\r) из CSV-файла с помощью sed, можно воспользоваться следующими подходами. Перед тем, как начать, важно помнить, что sed работает построчно, поэтому удаление символов возврата будет зависеть от структуры файла.

Использование sed

  1. Простой вариант для удаления \r:
    Вы можете использовать следующий команду sed, чтобы удалить все символы возврата каретки из файла. Эта команда создаст новый файл, в котором \r будет удален:

    sed 's/\r//g' файл.csv > новый_файл.csv

    В этой команде мы заменяем все вхождения символа \r на пустую строку, что фактически приводит к их удалению.

  2. Удаление \r в сочетании с конкретной строкой:
    Если вы хотите удалить \r только из определенного контекста, например, рядом с ";", вы можете сделать это следующим образом:

    sed 's/\r";"/";"/g' файл.csv > новый_файл.csv

    Эта команда заменяет вхождение \r";" на ";".

Использование tr

В качестве альтернативы можно использовать команду tr, которая предназначена для замены и удаления символов:

tr -d '\r' < файл.csv > новый_файл.csv

Эта команда удаляет все символы возврата каретки из файла.

Примечания

  • Команда sed не работает в режиме замены непосредственно в файле (то есть без создания нового файла) без флага -i (что иногда не рекомендуется по разным причинам).
  • Имейте в виду, что замена \r может привести к тому, что файл перестанет соответствовать формату CSV, поэтому всегда рекомендуется сохранять оригинальный файл до того, как вы будете вносить в него изменения.
  • Если ваш файл имеет и другую ошибку, где строки смешиваются, и вам необходимо объединить строки, это потребует более сложных команд sed для обработки.

Перл Как Альтернатива

Если вы знакомы с Perl, вы можете выполнить аналогичную задачу с помощью следующей команды:

perl -pe 's/\r//g' файл.csv > новый_файл.csv

Такой подход может быть полезен, если вам нужно больше возможностей для обработки текста.

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

Оцените материал
Добавить комментарий

Капча загружается...