Использование sed для удаления цифр и пробелов из строки

6

Я пытаюсь удалить первое вхождение цифры (й), точку, второе вхождение цифры (ей) и пробел перед словом ,

Я придумал это регулярное выражение:

sed 's/^[0-9]\+.[0-9]\+\s//' input.txt > output.txt

Образец текста:

2.14 Italien
2.15 Japonais

Мое регулярное выражение не работает, к сожалению. Существует проблема с \s но я не могу точно определить, что это ...

Кто-нибудь может помочь?

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

3.15 Chichewa
3.16 Chimane
3.17 Cinghalais
3.18 Créole de Guinée-Bissau
balteo
источник
Вы на самом деле просто хотите получить второй столбец?
slhck
Кажется, работает как задумано с GNU Sed 4.2.1. Может быть, поможет поместить класс персонажа в скобки «range»? такие как: [\s]\+ Кроме того, точка имеет особое значение, если ее не экранировать, возможно, вам стоит позаботиться об этом.
Ярослав Рахматуллин
@ ЯрославРахматуллин Как это может работать с простым GNU sed вызывать, когда OP использует метасимволы ERE ( + ) и расширенное RE не включены по умолчанию?
slhck
1
@slhck: это расширения GNU. Если вы избежите плюса, вам не нужно -r переключатель; и чтобы сделать его более запутанным, вы не можете избежать плюс с sed -r, \s работает так же. Оба перестают работать с --posix переключатель.
Dennis
Не уверен, что файл /usr/share/doc/sed-4.2.1-r1/NEWS.bz2 (Gentoo) вроде указывает на то, что опция --posix требуется для «стандартного» поведения, хотя в руководстве сказано -r требуется для расширенных регулярных выражений для работы ...
Ярослав Рахматуллин

Ответы:

12

Используемая вами команда должна работать как есть с GNU sed, Но с BSD sed, который, например, поставляется с OS X, не будет.

  • Если вы пытаетесь использовать Расширенные регулярные выражения - которые поддерживают + метасимвол - вам нужно явно включить их. Для BSD sed ты делаешь это с sed -Eи для GNU sed с sed -r,

    \+ в одиночестве делает с GNU sed когда ERE не включены, но это менее переносимо.

  • Вы используете Perl-как \s, который не существует для базовых и расширенных регулярных выражений. регулярное sed не поддерживает регулярные выражения Perl GNU sed поддерживает \s - но было бы удобнее просто добавить пробел к вашему регулярному выражению.

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

Таким образом, решение будет для GNU sed:

$ echo "2.12 blah" | sed -r 's/^[0-9]+\.[0-9]+ //'
blah

Или для BSD sed:

$ echo "2.12 blah" | sed -E 's/^[0-9]+\.[0-9]+ //'
blah

Таким образом, вам не нужно другое регулярное выражение для разных версий sed, С вашим примером:

$ cat test
3.15 Chichewa
3.16 Chimane
3.17 Cinghalais
3.18 Créole de Guinée-Bissau

$ sed -r 's/^[0-9]+\.[0-9]+ //' test
Chichewa
Chimane
Cinghalais
Créole de Guinée-Bissau

Если реальный проблема в том, что вы хотите получить второй столбец файла, разделенного пробелами, тогда вы делаете это неправильно. Либо использовать awkкак говорит @Srdjan Grubor, или используйте cut:

$ echo "2.12 foo bar baz" | cut -d' ' -f2-
foo bar baz

-f2- задает второй и все последующие столбцы, поэтому в качестве первого разделителя он будет взят в качестве первого пробела, а остальные будут выведены.

slhck
источник
Я запускаю GNU sed и пробовал ключ -r следующим образом: sed -r 's/[0-9]+\.[0-9]+ //' input.txt > out.txt но безрезультатно.
balteo
Привет slhck: Спасибо за подробный ответ. К вашему сведению, я использую Ubuntu и GNU sed.
balteo
Я протестировал все примеры, в том числе и с GNU sed, Что конкретно не работает? Какой результат вы получаете? Самое простое решение в вашем примере будет cut -d' ' -f2- хоть.
slhck
1
Ваш ввод не отформатирован так, как вы сказали. Пожалуйста, проверьте это более тщательно: после номеров у вас есть U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX а затем U+00A0 NO-BREAK SPACE, а не только один пробел. sed -r 's/^[0-9]+\.[0-9]+ //' input должен делать, если вы копируете все пространство между вашими числами и строкой в ​​фактическую команду.
slhck
1
POSIX-й эквивалент для Perl \s является [[:space:]]
glenn jackman
7

Почему бы не использовать awk?

cat  input.txt | awk '{print $2}' > output.txt
Srdjan Grubor
источник
Привет Срджан: Спасибо за ваш ответ. Я отредактировал свой пост, чтобы уточнить мою проблему.
balteo
Смотрите мой комментарий к slhck. Сожалею.
balteo
2

Если единственное, что нужно, это сбросить все, включая первый пробел, то этого достаточно.

sed -e 's/[^ ]* //'
vortex7
источник
Это будет работать без цифр, но не в этом случае.
balteo
Используя это: sed -r 's/[^ ]//' для файла с только начальным пробелом производит желаемый эффект.
balteo
Смотрите мой комментарий к slhck. Сожалею.
balteo
1

Вы также можете использовать grep:

grep -oP '[a-zA-Z]+$' input.txt > output.txt

mohit6up
источник
1

С любым седом:

sed 's/^[0-9]\{1,\}\.[0-9]\{1,\} //' 

Или, возможно, этого может быть достаточно:

sed 's/^[0-9.]\{1,\} //' file
Scrutinizer
источник