У меня есть файл, который имеет несколько имен хостов, связанных с IP-адресами, который выглядит следующим образом:
x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int.test.example.com 59.2.86.3
super.awesome.machine 123.234.15.6
Я хочу, чтобы это выглядело так:
x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int-test-example-com 59.2.86.3
super-awesome-machine 123.234.15.6
Как я могу заменить. (точки) из первого столбца с - (дефис), чтобы упростить сортировку по второму столбцу? Я думал об использовании sed для замены точек до первого пробела или замены каждой точки, кроме последних трех, но у меня возникают проблемы с пониманием регулярных выражений и sed. Я могу выполнять простые замены, но это над моей головой!
Это часть более крупного скрипта, который я писал на bash. Я застрял в этой части.
awk
основана наnawk
, так что все современныеawk
реализации должны иметьgsub
. На Солярисе может понадобиться/usr/xpg4/bin/awk
илиnawk
.Если вам нужно выполнить замены в первом поле, лучше всего использовать решение Rahul's awk, но имейте в виду, что оно может повлиять на интервал (поля перезаписываются с одним пробелом между ними).
Вы можете избежать этого, написав вместо этого:
В
-p
означает флаг «читать входной файл построчно и распечатать каждую строку после применения сценария дается-e
». Затем замените (s|pattern|replacement|
) первую последовательность непробельных символов (\S+
) на соответствующий шаблон ($&
) после замены всех.
на-
. Хитрость заключается в использовании,s|||e
гдеe
оператор будет оценивать выражение как замену. Таким образом, вы можетеtr/./-/
применить один replace ( ) к match ($&
) предыдущего (s|||e
).Если вам нужно заменить каждое
.
на,-
кроме последних 3 последних, на GNUsed
и при условии, что у вас естьrev
команда:источник
/r
работы).Sed - не самый простой инструмент для работы - см. Другие ответы для лучших инструментов - но это можно сделать.
Для того, чтобы заменить
.
на-
только до первого места, использованиеs
в цикле.(Обратите внимание, что некоторые реализации sed не поддерживают комментарии в одной строке. GNU sed поддерживает.)
Чтобы выполнить замену до последнего пробела:
Другая техника использует пространство для хранения sed. Сохраните бит, который вы не хотите изменять, в область удержания, выполните свою работу, а затем вызовите область удержания. Здесь я разбил строку на последнем месте и заменил точки на тире в первой части.
источник
Так как Рахул дал вам канонический ответ для вашего варианта использования, я подумал, что я попытаюсь ответить на главную проблему: заменить все, кроме последнего, x вхождений регулярного выражения:
Приведенный выше код (проверено) не предполагает наличие полей, разделенных пробелами. Он заменит все точки на линии с помощью тире, кроме последних 3-х точек. Замените
3
в коде по своему вкусу.источник
Вы можете использовать много разных инструментов для этого. Рахул Патил уже дал вам
gawk
один, так что вот несколько других:Perl
Этот
-a
переключатель заставляет perl автоматически разбивать входные строки на пробел и сохранять полученные поля в массив@F
. Первое поле, таким образом, будет$F[0]
так мы заменим (s///
) все вхождения.
с-
в первом поле , а затем напечатать весь массив.ракушка
Здесь цикл while читает файл и автоматически разделяется на пробелы. Это создает два поля
$first
и$rest
. Конструкция${first//pattern/replacement}
заменяет все вхожденияpattern
сreplacement
.источник
perlrun(1)
скажу, что-a
это «режим авторазделения», я предпочитаю думать о нем как о «awk
режиме»: DЯ считаю, что это немного легче читать, чем большое противное регулярное выражение. По сути, я просто разбил строку на два поля в пустом месте и использовал sed в первой части.
В зависимости от вашей оболочки вы также можете использовать $ {host //./-} вместо команды sed.
источник
Без использования
g
в конце команды вы можете сделать это ... Это просто заменит 1-е вхождение шаблонаисточник