У меня есть файлы конфигурации vm, из которых мне нужно распечатать все диски (26 буквенно-цифровых символов, за которыми следует .img), существующие в каждом файле.

Вот выдержка из одного из файлов

[root@~]# cat demo_vm.cfg
disk = ['file:/OVS/Repositories/0004fb00000300007b8afb76a3377693/VirtualDisks/0004fb0000120000a17dfe12ac74818f.img,xvda,w', 'file:/OVS/Repositories/0004fb00000300007b8afb76a3377693/VirtualDisks/0004fb0000120000e66ace31dac64d98.img,xvdb,w', 'file:/OVS/Repositories/0004fb00000300007b8afb76a3377693/VirtualDisks/0004fb000012000082fbb45a02e24096.img,xvdd,w']

Я хочу извлечь следующее (все ссылки на 26alphanum.img в файле):

0004fb0000120000a17dfe12ac74818f.img
0004fb0000120000e66ace31dac64d98.img
0004fb000012000082fbb45a02e24096.img

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

# awk -F [/,] '/disk/ { print $6}' demo_vm.cfg
0004fb0000120000a17dfe12ac74818f.img

Заранее спасибо. Я потратил часы, пытаясь разделить и использовать шаблоны регулярных выражений, но без окончательного результата. Это мой первый вопрос в SOverflow.

ИЗМЕНИТЬ

Вот 3 типа содержимого, помещенного в отдельные файлы (1 = один экземпляр 26 [alnum] .img, 2 = два экземпляра 26 [alnum] .img, 3 = три экземпляра 26 [alnum] .img)

# cat demo_vm_1.cfg
disk = ['file:/OVS/Repositories/0004fb00000300007b8afb76a3377693/VirtualDisks/0004fb000012000065a82a4df5e7112b.img,xvda,w']
[root ~]# cat demo_vm_2.cfg
disk = ['file:/OVS/Repositories/0004fb0000030000a079ca25909e5455/VirtualDisks/0004fb0000120000822cb8b0602ee042.img,xvda,w', 'file:/OVS/Repositories/0004fb0000030000a079ca25909e5455/VirtualDisks/0004fb000012000073d5fd864a0ba6b1.img,xvdb,w']
# cat demo_vm_3.cfg
disk = ['file:/OVS/Repositories/0004fb00000300007b8afb76a3377693/VirtualDisks/0004fb0000120000a17dfe12ac74818f.img,xvda,w', 'file:/OVS/Repositories/0004fb00000300007b8afb76a3377693/VirtualDisks/0004fb0000120000e66ace31dac64d98.img,xvdb,w', 'file:/OVS/Repositories/0004fb00000300007b8afb76a3377693/VirtualDisks/0004fb000012000082fbb45a02e24096.img,xvdd,w']
  • Начальный сценарий

У моего первоначального сценария, который создает команды удаления для файлов .cfg и отмеченных изображений внутри каждого из них, возникла проблема, когда cfg имел более одной ссылки на диск. Думаю, теперь я могу адаптировать его для использования grep -Eo вместо awk

  
strings=(`find  /vm_backup/VirtualMachines/*/vm.cfg`)                                                             
for i in "${strings[@]}"; do                                                                                      
echo "rm -f $i" >> drop_vm_final.sh                                                                               
awk -F [/,] '/disk/ { print $6}' "$i" | awk '{print "rm -f  /vm_backup/VirtualDisks/"$0}'  >>drop_vm_bkp_final.sh 
done                                                                                                              

3
koss 1 Дек 2020 в 22:43

3 ответа

Лучший ответ
$ grep -Eo '[[:alnum:]]{26}\.img' file
0000120000a17dfe12ac74818f.img
0000120000e66ace31dac64d98.img
000012000082fbb45a02e24096.img

Если это не все, что вам нужно, отредактируйте свой вопрос, чтобы предоставить более представительный образец ввода / вывода, для которого это не работает.

2
Ed Morton 1 Дек 2020 в 19:50

На основе вашего кода

awk -F [/,] '/disk/ { print $6}' demo_vm.cfg

Вы можете завершить print добавление $14 и $22

awk -F [/,] '{ print $6,$14,$22}' OFS='\n' demo_vm.cfg
0004fb0000120000a17dfe12ac74818f.img
0004fb0000120000e66ace31dac64d98.img
0004fb000012000082fbb45a02e24096.img

0
Carlos Pascual 2 Дек 2020 в 08:40

Не могли бы вы попробовать следующее на основе показанных вами образцов.

awk '
match($0,/[[:alnum:]]{26}\.img/){
  print substr($0,RSTART,RLENGTH)
}
'  Input_file

ИЛИ, чтобы получить все совпадающие значения в одной строке, попробуйте выполнить следующее.

awk '
{
  while(match($0,/[[:alnum:]]{26}\.img/)){
    print substr($0,RSTART,RLENGTH)
    $0=substr($0,RSTART+RLENGTH)
  }
}' Input_file

Объяснение: Добавление подробного объяснения выше.

awk '                                        ##Starting awk program from here.
{
  while(match($0,/[[:alnum:]]{26}\.img/)){   ##Running while loop to match alpha numerics 26 in number followed by .img if this match found then do following.
    print substr($0,RSTART,RLENGTH)          ##Printing matched sub string of that matched regex from current line.
    $0=substr($0,RSTART+RLENGTH)             ##Saving rest of the line(after matched string) to current line here.
  }
}' Input_file                                ##mentioning Input_file name here.
0
RavinderSingh13 1 Дек 2020 в 19:53