Заменить строку после последней точки в bash

У меня есть следующий шаблон в строке (IP-адрес):

123.444.888.235 

Я хочу заменить последнее число после точки на 0 , так что это будет:

 123.444.888.0 

Как я могу сделать это в bash или другом языке сценариев оболочки?

5 Solutions collect form web for “Заменить строку после последней точки в bash”

В любой оболочке POSIX:

 var=123.444.888.235 new_var="${var%.*}.0" 

${var%pattern} – это оператор, введенный ksh в 80-х годах, стандартизованный POSIX для стандартного языка sh и теперь реализованный всеми оболочками, которые интерпретируют этот язык, включая bash .

${var%pattern} расширяется до содержимого $var лишенного самой короткой строки, которая соответствует шаблону с конца (или равна $var если этот шаблон не совпадает). Таким образом, ${var%.*} (Где .* – это шаблон, который означает точку, за которой следует любое количество символов), расширяется до $var без права . и что следует за ним. В отличие от этого, ${var%%.*} Где самая длинная строка, соответствующая шаблону, разделяется, будет расширяться до $var без самой левой . и что следует за ним.

Это должно сработать.

 echo 123.444.888.235 | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\.\)[0-9]*/\10/' 

Обратите внимание, что последнее поле подстановки sed , \10 , является первым сопоставленным шаблоном ( \1 ), объединенным с литеральным нулем.

Несколько способов (все это предполагает, что вы хотите изменить последний набор чисел в строке):

 $ echo 123.444.888.235 | awk -F'.' -vOFS='.' '{$NF=0}1;' 123.444.888.0 

Здесь, -F'.' говорит awk для использования . как разделитель полей ввода и -vOFS='.' использовать его как разделитель выходного поля. Затем мы просто устанавливаем последнее поле ( $NF ) равным 0 и печатаем строку ( 1; – сокращенно awk для «print the current line»).

 $ echo 123.444.888.235 | perl -pe 's/\d+$/0/' 123.444.888.0 

-p указывает perl на печать каждой строки ввода после применения сценария, заданного -e . Сам скрипт – просто простой оператор замещения, который заменит одно или несколько чисел в конце строки на 0 .

 $ echo 123.444.888.235 | sed 's/[0-9]*$/0/' 123.444.888.0 

Та же идея в sed , используя [0-9] вместо \d .


Если ваша строка находится в переменной, и вы используете оболочку, которая поддерживает здесь строки (например, bash или zsh например), вы можете изменить выше:

 awk -F'.' -vOFS='.' '{$NF=0}1;' <<<$var perl -pe 's/\d+$/0/' <<<$var sed 's/[0-9]*$/0/' <<<$var 

Общий случай применения сетевой маски к IP-адресу:

Учитывая, что ваш вход является IP-адресом и что вы заменяете последний октет этого адреса на .0 , я предполагаю, что вы действительно пытаетесь достичь, это вычислить сетевую часть IP-адреса, используя 255.255.255.0 маска подсети.

Просто замена октетов нулями в порядке, если длина вашей сетевой маски делится на 8, но это не общий случай. Если вам когда-либо понадобится выполнить эту операцию для любой действительной (подсети) сетевой маски, вы можете сделать что-то вроде этого:

 function d2i() { echo $(( 0x$( printf "%02x" ${1//./ } ) )) } function i2d() { h=$( printf "%08X" "$1" ) echo $(( 0x${h:0:2} )).$(( 0x${h:2:2} )).$(( 0x${h:4:2} )).$(( 0x${h:6:2} )) } function ipmask() { i2d $(( $( d2i $1 ) & $( d2i $2 ) )) } ipmask 123.44.88.235 255.255.255.0 # outputs 123.44.88.0 ipmask 123.44.88.235 255.255.255.240 # outputs 123.44.88.224 

Это определяет 3 функции:

  • d2i() преобразует точечно-десятичную форму IP-адреса (или маски) в простое целое число
  • i2d() делает обратное – преобразует простое целое число в десятичную запятую
  • ipmask() просто вычисляет побитовое И адреса и сетевую маску для предоставления сетевой части адреса. Bash ожидает, что операнды & будут целыми числами.

Два вызова ipmask показывают, как сеть может быть рассчитана с IP-адреса для двух разных масок.


Примечание, как указано в вопросе, 123.444.888.235 является недопустимым IP-адресом. Я использовал 123.44.88.235 вместо этих примеров.

Альтернативный ответ sed :

 sed -r 's/(.*\.).*/\10/' 

Он группирует все до последней точки и заменяет полную строку содержимым группы, а затем 0.
Я использую -r, чтобы избежать столкновения с круглыми скобками.

  • разархивируйте два разных типа расширений файлов
  • Как получить две команды?
  • Разделить одну строку в массив символов, используя ТОЛЬКО bash
  • Что означает «if echo $ line | grep -F = &> / dev / null "делать?
  • Передача аргументов с пробелами и кавычками в скрипт (без цитирования всего)
  • Как всегда распечатать приглашение на новой строке и сохранить ввод
  • Как обращаться с обратным пространством во время чтения?
  • Какие настройки вы сделали в своем профиле оболочки, чтобы повысить производительность?
  • Использование подстановок / подстановочных знаков при открытии файлов с терминала
  • диапазон конкретных котов от / etc / hosts до диалогового окна
  • grep, чтобы увидеть, заканчивается ли строка определенной строкой
  • Linux и Unix - лучшая ОС в мире.