Замените все пробелы символом разрыва строки / абзаца, чтобы составить список слов - PullRequest
62 голосов
/ 05 декабря 2009

Я пытаюсь составить список греческого текста, который мы переводим в классе. Я хочу заменить каждый символ пробела или табуляции знаком абзаца, чтобы каждое слово отображалось в отдельной строке. Кто-нибудь может дать мне команду sed и объяснить, что я делаю? Я все еще пытаюсь выяснить, что это не так.

Ответы [ 8 ]

92 голосов
/ 05 декабря 2009

Для достаточно современных версий sed отредактируйте стандартный ввод, чтобы получить стандартный вывод с помощью

$ echo 'τέχνη βιβλίο γη κήπος' | sed -E -e 's/[[:blank:]]+/\n/g'
τέχνη
βιβλίο
γη
κήπος

Если ваши словарные слова находятся в файлах с именами lesson1 и lesson2, перенаправьте стандартный вывод sed в файл all-vocab с помощью

sed -E -e 's/[[:blank:]]+/\n/g' lesson1 lesson2 > all-vocab

Что это значит:

  • Класс символов [[:blank:]] соответствует либо одному пробелу, либо один символ табуляции.
    • Вместо этого используйте [[:space:]], чтобы сопоставить любой отдельный символ пробела (обычно пробел, табуляция, перевод строки, возврат каретки, подача формы и вертикальная табуляция).
    • Квантор + означает, что соответствует одному или нескольким предыдущим образцам .
    • Итак, [[:blank:]]+ - это последовательность из одного или нескольких символов, которые являются пробелом или табуляцией.
  • \n в замене - это нужная вам новая строка.
  • Модификатор /g в конце означает, что замена выполняется столько раз, сколько возможно, а не один раз.
  • Опция -E указывает sed использовать расширенный синтаксис регулярного выражения POSIX и, в частности, для этого случая квантификатор +. Без -E ваша команда sed становится sed -e 's/[[:blank:]]\+/\n/g'. (Обратите внимание на использование \+ вместо простого +.)

регулярные выражения, совместимые с Perl

Для тех, кто знаком с регулярными выражениями, совместимыми с Perl, и sed с поддержкой PCRE, используйте \s+, чтобы сопоставить серии хотя бы одного символа пробела, как в

sed -E -e 's/\s+/\n/g' old > new

или

sed -e 's/\s\+/\n/g' old > new

Эти команды читают ввод из файла old и записывают результат в файл с именем new в текущем каталоге.

Максимальная переносимость, максимальная грубость

Возвращаясь почти к любой версии sed начиная с Версия 7 Unix , вызов команды немного более барочный.

$ echo 'τέχνη βιβλίο γη κήπος' | sed -e 's/[ \t][ \t]*/\
/g'
τέχνη
βιβλίο
γη
κήπος

Примечания:

  • Здесь мы даже не предполагаем существование скромного квантификатора + и моделируем его с помощью одного пробела или табуляции ([ \t]), за которым следует ноль или более из них ([ \t]*).
  • Точно так же, предполагая, что sed не понимает \n для новой строки, мы должны дословно включить его в командную строку.
    • \ и конец первой строки команды являются маркером продолжения, который экранирует непосредственно следующую новую строку, а остальная часть команды находится на следующей строке.
      • Примечание: Не должно быть пробелов, предшествующих экранированному символу новой строки. То есть конец первой строки должен быть точно с обратной косой чертой, за которым следует конец строки.
    • Этот подверженный ошибкам процесс помогает понять, почему мир перешел на видимые символы, и вам нужно будет проявить некоторую осторожность при попытке выполнить команду с помощью функции копирования и вставки.

Примечание к обратным слешам и кавычкам

Команды выше всех использовали одинарные кавычки (''), а не двойные кавычки (""). Рассмотрим:

$ echo '\\\\' "\\\\"
\\\\ \\

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

56 голосов
/ 05 декабря 2009

Портативный способ сделать это:

sed -e 's/[ \t][ \t]*/\
/g'

Это настоящая новая строка между обратной косой чертой и косой чертой. Многие реализации sed не знают о \n, поэтому вам нужен буквальный перевод строки. Обратная косая черта перед новой строкой предотвращает недовольство sed новой строкой. (в сценариях sed команды обычно заканчиваются переводом строки)

С помощью GNU sed вы можете использовать \n в подстановке и \ s в регулярном выражении:

sed -e 's/\s\s*/\n/g'

GNU sed также поддерживает "расширенные" регулярные выражения (это стиль egrep, а не стиль perl), если вы зададите ему флаг -r, поэтому вы можете использовать +:

sed -r -e 's/\s+/\n/g'

Если это только для Linux, вы, вероятно, можете использовать команду GNU, но если вы хотите, чтобы она работала в системах с non-GNU sed (например, BSD, Mac OS-X), вы можете перейти с более портативным вариантом.

9 голосов
/ 18 декабря 2014

Все примеры, перечисленные выше для sed break на той или иной платформе. Ни одна из них не работает с версией sed, поставляемой на Mac.

Однако регулярное выражение Perl работает одинаково на любом компьютере с установленным Perl:

perl -pe 's/\s+/\n/g' file.txt

Если вы хотите сохранить вывод:

perl -pe 's/\s+/\n/g' file.txt > newfile.txt

Если вы хотите только уникальные вхождения слов:

perl -pe 's/\s+/\n/g' file.txt | sort -u > newfile.txt
6 голосов
/ 31 января 2012
  1. вариант 1

    echo $(cat testfile)
    
  2. Вариант 2

    tr ' ' '\n' < testfile
    
4 голосов
/ 27 марта 2015

Вы можете использовать POSIX [[:blank:]] для соответствия горизонтальному символу пробела.

sed 's/[[:blank:]]\+/\n/g' file

или вы также можете использовать [[:space:]] вместо [[:blank:]].

Пример:

$ echo 'this  is a sentence' | sed 's/[[:blank:]]\+/\n/g'
this
is
a
sentence
4 голосов
/ 05 декабря 2009

Это должно сделать работу:

sed -e 's/[ \t]+/\n/g'

[ \t] означает пробел ИЛИ табуляцию. Если вам нужен какой-либо вид пространства, вы также можете использовать \s.

[ \t]+ означает столько пробелов ИЛИ вкладок, сколько вы хотите (но не менее одной)

s/x/y/ означает замену шаблона x на y (здесь \n - новая строка)

g в конце означает, что вы должны повторять столько раз, сколько это происходит в каждой строке.

2 голосов
/ 30 апреля 2017

Вы также можете сделать это с помощью xargs:

cat old | xargs -n1 > new

или

xargs -n1 < old > new
0 голосов
/ 06 декабря 2009

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

gawk '{$1=$1}1' OFS="\n" file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...