1

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

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

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

jack
John
joe
Jen
Tom
Tim
Richard

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

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

3 ответа3

2

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

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

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

1

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

jack
john
joe
Jen
Tom
Edwa
rd
Tim
Richard

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

1

Регулярное выражение ^[^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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .