як замінити значення на обчислення в bash / sed


1

Я використовував bash sed для заміни ip адреси в групі файлів, тобто 10.1.1.x => 10.2.2.x-19:

file1: 10.1.1.29 => 10.2.2.10, 
file2: 10.1.1.30 => 10.2.2.11, 
file3: 10.1.1.31 => 10.2.2.12, 

тощо.

Я майже впорався з:

for file in ifcfg* ; do sed -e "s/10.1.1./10.2.2./" $file >tmp/$file ; done

але не вдалося зрозуміти, як обчислити та замінити останню позицію адреси (x => x-19)

це, мабуть, дуже просто ...

Відповіді:


1

Ось один із способів зробити це:

$ for file in ifcfg*; do
    num=$(grep IPADDR $file|awk -F. '{print $4}')
    sed -e "s/10.1.1.[0-9]\+/10.2.2.$(($num-19))/" $file >tmp/$file
  done

Це забирає вміст IP-адреси та скорочує її так, щоб це був 4-й октет, який зберігається у змінній $num. Потім ця змінна додається за допомогою 19під час sedкоманди. Мені потрібно sedбуло трохи розширити ваш оригінал , додавши до нього, [0-9]\+щоб видалити існуючий 4-й октет, щоб ми могли просто замінити його $num+19.


Дякую, але отримало повідомлення про помилку "sed: -e вираз №1, char 45: unterminated` s 'command "
rookie

@rookie - чи можете ви поділитися тим, як виглядають рядки, що містять IP-адреси? Ви це запускаєте /etc/sysconfig/network-scripts/ifcfg*?
slm

рядки виглядають як IPADDR = 10.1.1.x і так, начебто, я хочу змінити в / etc / sysconfig / network-script / ifcfg *, але я граю в скопійовану папку поки що
rookie

Чудово, спасибі велике !!! Якраз те, що мені було потрібно, коли залишився один в офісі ... Багато сонця тобі :-)
rookie

@rookie - дякуйте, будь ласка, позначте це як прийняту відповідь та підкажіть, якщо ви вважаєте, що це було корисним та найбільш підходящою відповіддю на ваше запитання, щоб інші знали, що ваша проблема вирішена. Тебе ж!
slm

2

У вас буде більше удачі робити це з awk, а не sed.

awk -F. '{printf ("%d.%d.%d.%d\n",$1,$2,$3,$NF-19)}'

або за вашим прикладом,

awk -F. '/10.1.1/ {printf ("10.2.2.%d\n",$1,$2,$3,$NF-19)}'

або

for file in ifcfg*
do
    awk -F. '/10.1.1/ {printf ("10.2.2.%d\n",$1,$2,$3,$NF-19)}' $file >tmp/$file
done

Щоб зберегти інші рядки та припустити, що xце останній елемент на лінії, яку потрібно замінити, ось що ви робите

for file in ifcfg*
do
    awk -F. '/10.1.1/ {printf ("%s.%d.%d.%d\n",$1,2,2,$NF-19)}
             !/10.1.1/ {print $0}' $file > tmp/$file
done

Дякую, але це дає мені купу файлів, які однакові: рядок із лише 10.2.2.0, а також мені потрібно зберігати інші рядки в оригінальному файлі, тепер вони перезаписані awk. (З моєю командою sed вище, старий вміст залишився, змінився лише IP-адреса)
rookie

У вас є інший вміст у тій же лінії? Можливо, вам доведеться налаштувати операцію друку, щоб зберегти цей вміст.
unxnut

інший вміст знаходиться в інших рядках, і рядок, який я хочу змінити, справді IPADDR = 10.1.1.x
rookie

Я просто змінив відповідь вище, щоб подбати про це.
unxnut

Добре, спасибі, це теж працює. Цей форум - прекрасний спосіб отримати допомогу! Дякую!
новобранець


0

Я використовую perl для цього:

$ grep '10\.' file[123]
file1:10.1.1.29
file2:10.1.1.30
file3:10.1.1.31

$ perl -i -pe 's/10\.1\.1\.(\d+)/ "10.2.2." . ($1 - 19) /ge' file[123]

$ grep '10\.' file[123]
file1:10.2.2.10
file2:10.2.2.11
file3:10.2.2.12
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.