Я пытаюсь написать команду sed для замены лишних пробелов в файле. Каждое слово должно иметь только один пробел между словами, но начальные пробелы и табуляции должны быть оставлены. Итак, файл:
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Станет:
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Я пробовал разные варианты
/^[ \t]*/!s/[ \t]+/ /g
Любые идеи были бы хорошы.
решение1
$ sed 's/\>[[:blank:]]\{1,\}/ /g' file
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Выражение, которое я использовал, соответствует одному или нескольким [[:blank:]]
(пробелам или табуляциям)после слова, и заменяет их одним пробелом. \>
Соответствует границе нулевой ширины между символом слова и не-символом слова.
Это было протестировано с родным OpenBSD sed
, но я думаю, что это должно работать sed
и с GNU. GNU sed
также использует \b
для сопоставления границ слов.
Вы также можете использовать sed -E
сокращение до
sed -E 's/\>[[:blank:]]+/ /g' file
Опять же, если \>
у вас не работает GNU sed
, используйте \b
вместо этого.
Обратите внимание, что хотя вышеприведенный пример текста сортируется правильно, это не так.довольноработа по удалению пробелов после знаков препинания, как после первого предложения в
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Для этого подойдет немного более сложный вариант:
$ sed -E 's/([^[:blank:]])[[:blank:]]+/\1 /g' file
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
При этом любой непустой символ, за которым следует один или несколько пробелов, заменяется на непустой символ и один пробел.
Или, используя стандарт sed
(и очень маленькую оптимизацию, которая будет выполнять замену только в том случае, если естьдва или болеепробелы/табуляции после не-пробела/табуляции),
$ sed 's/\([^[:blank:]]\)[[:blank:]]\{2,\}/\1 /g' file
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
решение2
POSIXly:
sed 's/\([^[:space:]]\)[[:space:]]\{1,\}/\1 /g; s/[[:space:]]*$//'
Который заменяет любую последовательность из одного или нескольких пробельных символов, следующих за непробельным символом, на этот непробельный символ и один символ SPC, а также удаляет конечные пробельные символы, которые покрывают пустые строки и строки с конечными пробелами (включая CR, находящиеся в конце строк из текстовых файлов Microsoft).