#regex #sed
Вопрос:
У меня есть досье config.txt которые состоят из строк, как показано ниже
$ cat config.txt | head -n 3
f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@192.168.3.4:26601
be9d757acee1f5b573ec18d1e056542bc282be23@169.172.56.77:26604
d40ec20a080468fcd5965493d904e4d536cf5767@10.129.101.3:26607
$ cat ip.txt | head -n 3
10.0.4.5
10.3.5.6
10.3.5.8
Я хотел бы заменить IP-адрес на config.txt с включенным ip ip.txt файл соответственно
ожидаемый результат составляет
f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@10.0.4.5:26601
be9d757acee1f5b573ec18d1e056542bc282be23@10.3.5.6:26604
d40ec20a080468fcd5965493d904e4d536cf5767@10.3.5.8:26607
Поскольку IP-адреса в файле конфигурации являются динамическими, мне нужно использовать регулярное выражение в sed для замены IP-адреса.
для примера:
$ echo "f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@192.168.3.4:26601" | sed "s/*@ :*/*@10.0.4.5:*/g"
но это не обновление ip-адресов. Я очень новичок в регулярном выражении в написании сценариев. Пожалуйста, помогите!
Комментарии:
1. Избегайте Бесполезного Использования Cat ™ с
head -n3 config.txt
, кстати.
Ответ №1:
Ну, в этом случае можно использовать sed
и регулярное выражение. Вы можете сначала объединить файлы, а затем использовать регулярное выражение для перетасовки строк:
paste config.txt ip.txt | sed 's/@[^:]*(.*)t(.*)/@21/'
Обратите внимание, что это sed
работает только в контексте одной строки. Но регулярное выражение не является «динамическим», если the ip's in config file are dynamic
тогда вам следует использовать что-то «большее», чем регулярное выражение, лучше полный язык программирования с поддержкой карт и внутреннего состояния, например awk
, но также perl
или python
.
Ответ №2:
Способ использования awk
вместо этого. Сначала он считывает ip.txt
и сохраняет свое содержимое в массиве, индексируемом по номеру строки , а затем для каждой строки config.txt
заменяет IP-адрес в нем на адрес из соответствующей строки ip.txt
:
$ awk 'FNR==NR { ips[FNR] = $0; next }
{ sub(/@[^:] :/, "@" ips[FNR] ":"); print }' ip.txt config.txt
f03889d9abcb6a16155411bb8e0a34dddb5c8e4c@10.0.4.5:26601
be9d757acee1f5b573ec18d1e056542bc282be23@10.3.5.6:26604
d40ec20a080468fcd5965493d904e4d536cf5767@10.3.5.8:26607
Ответ №3:
Другой способ:
paste -d~ config.txt ip.txt | while IFS="~" read config ip;
do
echo $config | sed -r "s/([a-z0-9] )@(([0-9]{1,3}.?){4})(:[0-9] )/1@$ip4/g";
done;
Ответ №4:
Вот чистый ответ sed. Я прокомментировал это. Выложи содержимое на мой.сед и зови сед -н -ф мой.сед config.txt ip.txt
# We concat config.txt and ip.txt to a single line like
# f...c@192.168.3.4:26601|b...3@169.172.56.77:26604|d...7@10.129.101.3:26607|;10.0.4.5;10.3.5.6;10.3.5.8
# the characters "|" and ";" are used as separators
# the records of config.txt are identified by @,
# those of ip.txt the pattern ^[0-9](.[0-9]){3}
# if it's a config.txt line append "|" and append it to the hold space
/@/ {
s/$/|/
H
}
# if it's a ip.txt line put a ";" before it and append it to the hold space
/^[0-9] (.[0-9] ){3}/ {
s/^/;/
H
}
# Now the two files are read. We do the replacements at the end of input
$ {
x
# after having deleted all newlines the pattern spaces consists
# of one line as mentioned above
s/n//g
:b
# now we replace recursively the ip adress in the first "|"
# limited column by the ip adress in
# the first ";" limited column. (:b ist the beginning of the loop)
# 1. group: sequence of not | characters ended by @<ip-adress>:<not | characters>
# 2. group: the characters including the "@"
# 3. group: part of the ip adress pattern
# 4. group: the characters from : to "|" (excluded)
# 5. group: the sequence of not ";" characters followed by ";"
# 6. group: the replacement ip adress
# 7. group: part of the replacement ip adress pattern
# The "," in the replacement replaces the first "|" in order
# to enable recursion (see 1. group above)
s/(([^|]*@)[0-9] (.[0-9] ){3}(:[^|]*))|([^;]*);([0-9] (.[0-9] ){3})/264,5/
tb
# replace all , except the last one with newlines
s/,(.)/n1/g
# replace the last ","
s/,//
p
}
Ответ №5:
Это может сработать для вас (GNU sed amp; cat):
cat -n ipFile | sed -E 's/t(.*)/s#@.*:#@1:#/' | sed -f - configFile
Добавьте номера строк в IP-файл.
Замените каждую строку в IP-файле командой подстановки sed для ip-адреса.
Вызовите второе приложение sed, используя файл конфигурации в качестве источника, и примените команду подстановки из файла IP к каждой строке в файле.
N. B. -f
Опция принимает команду sed из файла, в этом случае файл -
передается по конвейеру из предыдущего приложения sed.
Другое решение:
paste configFile ipFile | sed -E 's/@.*:(S*)t(S )/@2:1/;/@/!d'
Это заменит добавленный ip-адрес в файле конфигурации.
N. B. Если в IP-файле больше строк, чем /@/!d
в файле конфигурации, убедитесь, что дополнительные строки не включены.