Grep и отфильтровывать значения из файла - PullRequest
0 голосов
/ 05 марта 2019

У меня есть требование grep значений из xml-файла в файле примера оболочки ниже: test.xml

<wtc-import>
      <name>WTCImportedService-288-rap04</name>
      <resource-name>CAC040F</resource-name>
      <local-access-point>lap01</local-access-point>
      <remote-access-point-list>rap04</remote-access-point-list>
      <remote-name>CAC040F</remote-name>
    </wtc-import>
    <wtc-import>
      <name>WTCImportedService-289-rap04</name>
      <resource-name>CAD040F</resource-name>
      <local-access-point>lap01</local-access-point>
      <remote-access-point-list>rap04</remote-access-point-list>
      <remote-name>CAD040F</remote-name>
    </wtc-import>
   <wtc-import>
      <name>WTCImportedService-290-rap04</name>
      <resource-name>CAE040F</resource-name>
      <local-access-point>lap01</local-access-point>
      <remote-access-point-list>rap04</remote-access-point-list>
      <remote-name>CAE040F</remote-name>
    </wtc-import>
    <wtc-import>
  <name>WTCImportedService-289-rap04</name>
  <resource-name>CAD040F</resource-name>
  <local-access-point>lap01</local-access-point>
  <remote-access-point-list>rap04</remote-access-point-list>
  <remote-name>CAD040F</remote-name>
</wtc-import>

Необходимо выполнить grep для всех значений, связанных с этим файлом, и, наконец, при наличии дублированного имени ресурсаприсутствует удалить дубликат из выходного файла

Выполненный вывод:

CAC040F
CAD040F
CAE040F

ресурс CAD040F является дубликатом, поэтому в ожидаемом выводе он только что появился один раз

Попытка:

grep 'resource-name' test.xml | awk -F">" '{print $2}' | awk -F"<" '{print $1}' 

и это работает хорошо .. как насчет фильтрации дубликатов после этого?

Ответы [ 4 ]

0 голосов
/ 05 марта 2019

Просто оптимизация скорости, сравните с @ stack0114106, что уже работа

awk -F '[<>]' '$2 == "resource-name" && ! ( $3 in List) { print $3; List[$3] } ' test.xml
0 голосов
/ 05 марта 2019

Если вы предпочитаете bash regex, попробуйте следующее:

declare -A name
regex="<remote-name>([^<]+)</remote-name>"

while read -r line; do
    if [[ $line =~ $regex ]]; then
        name["${BASH_REMATCH[1]}"]=1
    fi
done < "test.xml"

for i in "${!name[@]}"; do
    echo "$i"
done
0 голосов
/ 05 марта 2019

Вы можете сделать это с помощью одной команды awk

awk -F"[<>]" '/resource-name/ && !seen[$3]++ { print $3 } ' test.xml

с вашим примером XML-файла

$ awk -F"[<>]" '/resource-name/ && !seen[$3]++ { print $3 } ' test.xml
CAC040F
CAD040F
CAE040F

$
0 голосов
/ 05 марта 2019

Если вы уже получаете выходные данные и просто хотите удалить дубликаты, самый простой способ сделать это - передать выходные данные в сортировку, а затем в uniq, чтобы ваша команда выглядела следующим образом

grep 'resource-name' test.xml | awk -F">" '{print $2}' | awk -F"<" '{print $1}' | sort | uniq
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...