Как вы анализируете слова из файла?

Привет, скажем, у меня есть файл, который выглядит так

<jack,
john.
................
,joe
..........Jen..
>Tom
Edwa4rd
4Tim
Richard

Как я могу превратить это в чистый список, как

jack
John
joe
Jen
Tom
Tim
Richard

Обратите внимание, что Эдварда нет в списке

Используя команды Linux? Вероятно, grep и / или sed

3 ответа

Пытаться egrep -o '[A-Za-z](.*[A-Za-z])?' < infile | egrep -o '[A-Za-z]+' > outfile для вашего примера.

Первая часть выбирает именные вещи (должна начинаться с буквы и заканчиваться буквой, но может содержать что-либо между ними), а затем вторая egrep фильтрует нас до только имен, которые состоят из букв.

Глядя на это, я уже вижу несколько путей создания входных данных, которые могут привести к сбою этих выражений и их неправильному совпадению (ну, это будет соответствовать тому, как написано, но вы оставили двусмысленности - как должен ..Richard..<Tim?.. быть обработанным?), но было легко собрать это воедино на основе входных данных - сценарии оболочки часто менее чем на 100% математически корректны для всех возможных входных данных, но лучше знают ваш входной домен и выполняют работу с выражениями и командами это работает достаточно хорошо для ввода, который вы должны обработать.

Использование grep -o '[[:alpha:]]\+' извлечь все "слова".

jack
john
joe
Jen
Tom
Edwa
rd
Tim
Richard

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

Регулярное выражение ^[^a-zA-Z]*([a-zA-Z]+)[^a-zA-Z]*$ должно сработать.

  1. ^ соответствует началу строки
  2. [^a-zA-Z]* соответствует нулю или более вхождений не-буквы
  3. [a-zA-Z]+ соответствует одному или нескольким вхождениям буквы
  4. [^a-zA-Z]* соответствует нулю или более вхождений не-буквы
  5. $ соответствует концу строки

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

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

sed -rn 's/^[^a-zA-Z]*([a-zA-Z]+)[^a-zA-Z]*$/\1/p' inputfile

Вместо печати вы можете записать непосредственно в выходной файл:

sed -rn 's/^[^a-zA-Z]*([a-zA-Z]+)[^a-zA-Z]*$/\1/w outputfile' inputfile
Другие вопросы по тегам