Заменить символ, кроме последних x входов

У меня есть файл с кучей имен хостов, коррелированный с 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 … я могу выполнять простые замены, но это происходит над моей головой: D.

Это часть большого скрипта, который я писал в bash. Я застрял в этой части …

  • добавить в файл добавочный столбец идентификатора
  • Раскрашивание хвостового выхода с помощью sed
  • Способ вставки определенного столбца, когда в терминале
  • Строки соответствия, начинающиеся с одного шаблона в двух текстовых файлах
  • удалить строки в файле csv старше 7 дней
  • Правильно ли замените & & XML?
  • Удаление нескольких строк в файле
  • Sed удалить строку, если n-й символ не является конкретным символом
  • 9 Solutions collect form web for “Заменить символ, кроме последних x входов”

    Вы можете использовать AWK

     awk '{gsub(/-/,".",$1);print}' infile 

    объяснение

    По умолчанию awk разбивает строку по пробелам. Таким образом, первый столбец строки ( $1 в awk -ese) будет тем, который вы хотите выполнить подстановками. Для этого вы можете использовать:

      gsub(regex,replacement,string) 

    для выполнения требуемой замены.

    Обратите внимание, что gsub поддерживается только для gawk и nawk но во многих современных дистрибутивах awk – это программная ссылка на gawk .

    Если вам нужно сделать замены в первом поле, лучше всего использовать решение awk Rahul, но будьте осторожны, это может повлиять на интервал (поля переписываются с одним пробелом между ними).

    Вы можете избежать этого, написав вместо этого:

     perl -pe 's|\S+|$&=~tr/./-/r|e' file 

    Флаг -p означает «читать входной файл по строке и печатать каждую строку после применения сценария, заданного -e ». Затем замените ( s|pattern|replacement| ) на первую последовательность непространственных символов ( \S+ ) совпадающим шаблоном ( $& ) после замены всех . с - . Хитрость заключается в использовании s

    e где оператор e будет оценивать выражение в качестве замены. Таким образом, вы можете иметь одну замену ( tr/./-/ ), применяемую к совпадению ( $& ) предыдущего ( s

    e ).

    Если вам нужно заменить каждый . с - за исключением последних 3 последних, с GNU sed и при условии, что у вас есть команда rev :

     rev file | sed 's/\./-/4g' | rev 

    Sed – не самый простой инструмент для работы – см. Другие ответы на лучшие инструменты, но это можно сделать.

    Заменить . by - только до первого пространства, используйте s в цикле.

     sed -e ' : a # Label "a" for the branching command s/^\([^ .]*\)\./\1-/ # If there is a "." before the first space, replace it by "-" ta # If the s command matched, branch to a ' 

    (Обратите внимание, что некоторые реализации sed не поддерживают комментарии в той же строке. GNU sed делает.)

    Вместо этого выполнить замену до последнего места:

     sed -e ' : a # Label "a" for the branching command s/\.\(.* \)/-\1/ # If there is a "." before the last space, replace it by "-" ta # If the s command matched, branch to a ' 

    Другой метод использует пространство для хранения sed. Сохраните бит, который вы не хотите изменять в пространстве удержания, выполните свою работу, а затем вспомните пространство удержания. Здесь я разделил строку в последнем пространстве и заменил точки пунктиром в первой части.

     sed -e ' h # Save the current line to the hold space s/.* / / # Remove everything up to the last space x # Swap the work space with the hold space s/[^ ]*$// # Remove everything after the last space y/./-/ # Replace all "." by "-" G # Append the content of the hold to the work space s/\n// # Remove the newline introduced by G ' 

    Поскольку Рахул дал вам канонический ответ для вашего случая использования, я подумал, что я бы наткнулся на ответную проблему: заменяя все, кроме последних x появлением регулярного выражения:

     perl -pe ' $count = tr{.}{.}; # Count '.' on the current line $x = 3; next LINE if $count <= $x; while(s{\.}{-}){ # Substitute one '.' with a '-' last if ++$i == $count - $x # Quit the loop before the last x substitutions } $i = 0 ' your_file 

    Вышеприведенный код (проверенный) не предполагает, что у вас есть поля, разделенные пробелами. Он заменит все точки на линии тире, за исключением последних 3 точек. Замените 3 в коде по своему вкусу.

    Для этого вы можете использовать множество различных инструментов. Рахул Патил уже дал вам gawk поэтому вот несколько других:

    • Perl

       perl -lane '$F[0]=~s/\./-/g; print "@F"' file 

      Переключатель -a заставляет perl автоматически разбивать входные строки на пробелы и сохранять полученные поля в массиве @F . Поэтому первое поле будет $F[0] поэтому мы заменим ( s/// ) все вхождения . с - в первом поле, а затем распечатать весь массив.

    • оболочка

        while read -rab; do printf "%s %s\n" "${a//./-}" "$b"; done < file 

      Здесь цикл while считывает файл и автоматически разбивается на whitespace. Это создает два поля: $first и $rest . Конструкция ${first//pattern/replacement} заменяет все вхождения pattern replacement .

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

     while read -r host ip; do echo "$(sed 's/\./-/g' <<< "$host") $ip" done < input_file 

    В зависимости от вашей оболочки вы также можете использовать $ {host //./-} вместо команды sed.

     sed 's/\./-/' <file name> 

    Без использования g в конце команды вы можете это сделать … Это просто заменит 1-е появление шаблона

    Interesting Posts

    Присоединившись к пользователю AD, изменив на

    Выбор управляемого коммутатора с Linux для использования в проекте сетки (batman-adv)

    Как я могу получить доступ к общей папке из R на Ubuntu на второй компьютер Ubuntu с помощью Samba?

    может ли связать цветную тему с буфером?

    Установите выравнивание числовых столбцов при разделении данных

    Добавление второго графического процессора значительно снижает мою графическую производительность

    Загрузка HP-UX из SAN

    Чтение разрешений на чтение запрещено, несмотря на наличие достаточных разрешений

    Ошибка inode ext2 fs

    Как начать работу с методами ввода?

    Как настроить mutt для отображения заголовка даты в моем локальном часовом поясе в пейджере?

    Cygwin на Windows: не удается открыть дисплей

    Удалить абзац из файла

    Поддерживается ли в Linux поддержка звуковой карты Sound Sound Blaster X-FI Surround 5.1 SB1090 USB?

    Чтение файла журнала между двумя датами

    Linux и Unix - лучшая ОС в мире.