У меня есть файл .csv (на Mac), который имеет кучу пустых строк, например:
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum ","2","3","4"
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum ","2","3","4"
Который я хочу преобразовать в:
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum ","2","3","4"
"1", "2", "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum ","2","3","4"
Я знаю, что должен быть один лайнер, но я не знаю awk или sed. Любые советы с благодарностью!
shell
text-processing
sed
awk
pitosalas
источник
источник
Ответы:
Вы можете использовать
-v
режим grep (invert match), чтобы сделать это:Обратите внимание, что это должны быть разные файлы из-за того, как работают перенаправления оболочки. Выходной файл открывается (и очищается) до его чтения. Если у вас есть moreutils (не по умолчанию в Mac OS X), вы можете использовать,
sponge
чтобы обойти это:Но, конечно, тогда вам будет труднее вернуться назад, если что-то пойдет не так.
Если вы «пустые строки» на самом деле можете содержать пробелы (звучит так, как они), то вы можете использовать это вместо:
Это будет игнорировать пустые строки, а также строки, содержащие только пробелы. Конечно, вы можете сделать то же самое
sponge
преобразование на нем.источник
egrep -v '^[[:space:]]*$'
... note grep -> egrep и странный новый шаблонiconv -f utf16le file.csv | head
илиiconv -f utf16be file.csv | head
Самый простой вариант просто
grep .
. Здесь точка означает «соответствовать чему угодно», поэтому, если строка пуста, она не соответствует. В противном случае он печатает всю строку как есть.источник
Для того, чтобы удалить пустые строки, в месте , с ksh93:
Оператор
<>;
перенаправления специфичен для ksh93 и аналогичен стандартному<>
оператору, за исключением того, что ksh усекает файл после завершения команды.sed '/./!d'
это запутанный способ написанияgrep .
, но, к сожалению, GNU grep по крайней мере жалуется, если его стандартный вывод указывает на тот же файл, что и его стандартный ввод. Вы бы сказали, что можно написать:Но, к сожалению, в ksh93 есть ошибка (по крайней мере, в моей версии (93u +)), в которой файл кажется обрезанным до нулевой длины в этом случае.
Кажется, обойти эту ошибку, но теперь, это гораздо более запутанный, чем команда sed.
источник
awk '/./' file 1<>; file
который работал. Для меня это даже яснее, чемsed '/./!d'
Вот
Perl
одна строка для этого:РЕДАКТИРОВАТЬ: Улучшен код, основанный на комментариях ruakh ниже.
источник
perl -ni -e '/./ and print' yourfile
$
- это якорь (то есть с нулевой шириной), поэтому он исключает символ новой строки. Что касается лишнего пространства, это причина, по которой я добавил, что/x
я не хотелPerl
пытаться интерполировать `$ \` в регулярное выражение$
, учитывая, что у вас есть\n
. (В качестве альтернативы - вам не нужно\n
, учитывая, что у вас есть\s*
и$
;; но я думаю, чтоs/^\s*\n//
становится понятнее, что новая строка удаляется.) Вам также не нужно/m
; это не влияет на эту команду. И как только вы избавитесь от$
и пространства, вам не понадобится/x
.\n
Сам можно удалить; то , что вы не можете сделать , это удалить как$
и\n
. Такs/^\s*//
что будет проблема, которую вы описываете, ноs/^\s*$//
было бы хорошо, из-за\s*
и$
. (Вы понимаете, о чем я?)$
может соответствовать перед новой строкой (при условии, что либо/m
флаг включен, либо символ новой строки является самым последним символом строки, либо и тем, и другим), но он также может соответствовать концу строки. Например,"abc" =~ m/^abc$/
это правда. В случае\s*$
,\s*
достаточно жадный, чтобы съесть новую$
строку , а затем совпадения до конца строки. (Но я думаюs/^\s*\n//
, что в любом случае это яснее, так что ваш ответ так же хорош, как и сейчас.)Исходя из разъяснений в комментариях к вашему вопросу, что-то вроде:
может делать что хочешь.
Пустой разделитель записей - это особый случай, который говорит о том,
awk
что записи должны быть абзацами (разделенными последовательностями пустых строк). Установка в качестве разделителя выходной записи пустой строки также означает, что содержимое этих абзацев (без разделителей) должно быть объединено.1
это просто истинное условие для печати каждой записи.Это, однако, пропустит завершающий перевод строки, так что вы можете сделать:
источник
Я знаю, что было бы легче, если бы я дал файл, но, к сожалению, он содержал конфиденциальную информацию, которой я не мог поделиться. В то же время я написал мне сценарий ruby, который, казалось, сделал свое дело:
Спасибо всем за помощь!
источник
производит
источник
Я нашел идею для возможного решения на стеке потока .
sed -i ':a;N;$!ba;s/[^"]\n\s*\n/ /g' file.csv
Вам, вероятно, следует сделать резервную копию вашего csv-файла перед его тестированием, но по крайней мере для предоставленного вами примера он работает безупречно.
Хорошее объяснение внутренней работы этого выражения предлагается в ответе, я просто отредактировал его, чтобы искать строки, которые не заканчиваются на
"
([^"]\n
).источник
Если из вашего собственного ответа вы хотите удалить символы новой строки, содержащиеся внутри строк в кавычках, вы можете сделать следующее:
Вы также можете использовать
-i
флаг Perl для редактирования файлов на месте .Или с GNU awk:
или же:
(если вы боретесь за самый короткий)
Обратите внимание, что предполагается, что во входных данных нет экранированных двойных кавычек.
источник
По сути, похоже, что вы хотите больше, чем удаление пустых строк, но удалить каждую последовательность из 2 или более символов новой строки.
Что вы могли бы сделать с Perl:
Вы также можете использовать
-i
флаг Perl для редактирования файлов на месте .источник
Существует более короткий способ удаления пустых строк в
AWK
:awk 'NF' file
Но чтобы получить желаемый результат, все, что нужно, - это просто один вкладыш:
awk 'NF {printf("%s ", $0); i++;} !(i % 2) {printf("\n");}' file
объяснение
В
AWK
, пустая строка означает, что строка / запись не имеет полей, то естьNF
переменная (Количество полей) равна нулю. Одна строка выше будет выполняться только приNF > 0
печати всех строк, кроме пустых.i++
Является непустой строкой счетчика.!(i % 2)
Используется для того , чтобы напечатать два последовательных непустые строки в пути нужного выхода, то есть, каждый раз , кратное 2 найдено,modulo
заявление!(i % 2)
дает 1, то , что завершает конкатенацию двух непустых строк.источник
Вы можете использовать Vim в режиме Ex:
v/./
найти пустые строкиd
удалятьx
сохрани и закройисточник