преобразование текстовых данных в Unix или Linux с помощью текстового редактора, такого как sed или awk или tr - PullRequest
0 голосов
/ 08 мая 2018

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

Ниже приведен пример файла.

$ cat file1
mynetgroup-test (192.19.23.57,-,) (192.19.23.58,-,)

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

$ cat file1 | sed -e 's/[(,) ]/\n/g' | tr -d "-" | sed '/^$/d'
mynetgrouptest
192.19.23.57
192.19.23.58

Ответы [ 4 ]

0 голосов
/ 08 мая 2018

С GNU awk для нескольких символов RS:

$ awk -v RS='\\s+' '{gsub(/[-,)(]/,"")}1' file
mynetgrouptest
192.19.23.57
192.19.23.58
0 голосов
/ 08 мая 2018

Как насчет использования grep?

$ egrep -o '[a-z][a-z-]+|[0-9]+(\.[0-9]+){3}' input.txt
mynetgroup-test
192.19.23.57
192.19.23.58

Или, конечно, grep -E, если ваша ОС предпочитает не использовать egrep.

Это решение просто сопоставляет шаблоны, которые выглядят как имена хостов и IP-адреса, и (благодаря опции -o от grep) печатает только совпадающие фрагменты в порядке их просмотра.

В качестве альтернативы можно использовать опцию grep -e для включения нескольких регулярных выражений:

egrep -o -e '[a-z][a-z-]+' -e '[0-9]+(\.[0-9]+){3}' input.txt

Конечно, если вы действительно хотите использовать другие инструменты, может сработать следующее:

$ awk '{print $1; for(i=2;i<=NF;i++) { gsub(/[^0-9.]/,"",$i); print $i } }' input.txt
mynetgroup-test
192.19.23.57
192.19.23.58

Это печатает первое поле, затем проходит по оставшимся полям, удаляя нежелательные символы, затем печатая поля.

Другая альтернатива awk может быть такой:

$ awk '{for(i=2;i<=NF;i++) { gsub(/[^0-9.]/,"",$i) } } 1' OFS="\n" input.txt

Это делает те же пошаговые поля, а затем печатает всю запись, используя сокращение 1 в конце скрипта. Назначение переменной OFS немного отличается от опции -v, но в этом случае работает так же.

Если вы не возражаете против труб, вы можете сделать что-то подобное с помощью sed:

tr ' ' '\n' < input.txt | sed -ne '/^[a-z]/{p;b' -e '}' -e 's/[^0-9.]//gp'

Это разделяет слова на отдельные строки для облегчения обработки с помощью sed (а также для макета конечного формата вывода). Затем сценарий sed (1) печатает любую строку, начинающуюся с буквы, при условии, что это имя хоста, затем b ranches, которая переносит нас на следующую строку, и (2) удаляет любые символы, не являющиеся IP-адресами, из любых других строк. и печатает их.

Обозначение sed здесь было протестировано с помощью bsd sed, но должно работать и с GNU sed.

0 голосов
/ 08 мая 2018

с sed

$ sed -E 's/\((([0-9]+\.){3}[0-9]+),-,\)/\n\1/g' file

mynetgroup-test 
192.19.23.57 
192.19.23.58

вы можете точно настроить соответствие IP-адреса, но эта эвристика должна быть в порядке.

0 голосов
/ 08 мая 2018

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

awk '{while(match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)){print substr($0,RSTART,RLENGTH);$0=substr($0,RSTART+RLENGTH+1)}}'  Input_file

РЕДАКТИРОВАТЬ1: В случае, если ваш Input_file на 100% такой же, как показанные примеры, то следующее также может помочь вам в этом.

awk -v RS=" " '{gsub(/\(|,|-|\)/,"");gsub(/$\n$/,"")} 1'   Input_file

РЕДАКТИРОВАТЬ 2: , взяв немного вдохновения от решения Готи сэра тоже.

awk -v RS=" " '!/[a-zA-Z]+/{gsub(/[^0-9.]+/,"");gsub(/$\n$/,"")} 1'   Input_file
...