bash - 단일 문자로 분할하고 찾은 항목을 문자열로 일치시킵니다.

bash - 단일 문자로 분할하고 찾은 항목을 문자열로 일치시킵니다.

간단히 말해서:

다음 입력(노드의 장치 "목록"과 같은 것)이 주어지면 IP 주소를 얻고 싶지만 "라우터"라는 장치에서만 얻을 수 있습니다. (router1., gw. 또는 기타가 아님):

gw.bec2,10.41.113.216,HNA: router.bec2,4|router.bec2,192.168.156.131,online,0
gw1.ros78,192.168.159.114,HNA: router.ros78,4|gw1test.ros78,10.41.112.118,HNA: router.ros78,8|gw34.ros78,192.168.159.13,HNA: router.ros78,4|router.ros78,192.168.159.125,online,0
router.jed99,10.41.118.189,online,0|router1.jed99,10.41.118.190,online,0|router2.jed99,10.41.118.191,erstellt: 09.10.14,9

가장 좋은 방법은 예제에서 다음 값만 추출하는 것입니다.

192.168.156.131
192.168.159.125
10.41.118.189

매우 긴 이야기:

노드 이름과 노드 ID를 얻기 위해 XML 파일을 구문 분석하고 있습니다. 이제 "라우터"라는 장치의 IP도 필요합니다. XML 파일은 각 노드에 대한 장치 목록인 "devices" 속성을 제공합니다. 위에서는 세 노드의 예를 볼 수 있습니다. 이 "목록"은 "|" 파이프로 구분되며 장치 및 해당 속성은 쉼표 ","로 표시됩니다.

지금까지는 노드 이름과 노드 ID를 얻을 수 있었지만 지금은 IP를 얻기가 어렵습니다.

xpath -q -e 'concat(/nodes/node[@name="bec2"]/@name,"-",/nodes/node[@name="bec2"]/@nodeid,"-",/nodes/node[@name="bec2"]/@devices)' map.xml
# output:
# bec2-169-gw.bec2,10.41.113.216,HNA: router.bec2,4|router.bec2,192.168.156.131,online,0
# but needed output would be something like:
# bec2-169-192.168.156.131

비슷한 것을 시도했지만 장치의 순서가 노드마다 다르기 때문에 숫자로 필드를 선택하는 것은 적절하지 않은 것 같습니다.

xpath -q -e 'concat(/nodes/node[@name="bec2"]/@name,"|",/nodes/node[@name="bec2"]/@nodeid,"|",/nodes/node[@name="bec2"]/@devices)' map.xml | cut -d"|" -f 1,2,4
xpath -q -e 'concat(/nodes/node[@name="ros78"]/@name,"|",/nodes/node[@name="ros78"]/@nodeid,"|",/nodes/node[@name="ros78"]/@devices)' map.xml | cut -d"|" -f 1,2,4
# output:
# bec2|169|router.bec2,192.168.156.131,online,0
# ros78|1054|gw1test.ros78,10.41.112.118,HNA: router.ros78,8

내 생각은 파이프로 분할하고 각 장치를 가져온 다음 "router."라는 문자열을 검색한 다음 발견된 장치를 가져오고 쉼표로 분할하여 두 번째 속성을 얻는 것입니다.

그런데 문자로 분할하고 숫자로 결과를 선택하지 않고 검색 문자열로 결과를 선택하는 것이 가능한지, 어떻게 가능한지 궁금합니다.

감사해요.

(300 평판이 필요하기 때문에 xpath 태그를 추가할 수 없습니다)

답변1

사용 grepcut:

<file grep -Eo 'router\.[^,]*,[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d, -f2
  • grep부분 뒤에는 router\.쉼표가 아닌 문자가 여러 개 오고 [^,]*그 뒤에 쉼표 ,와 IP 주소가 옵니다.
  • cut그런 다음 및 구분 기호를 사용하여 첫 번째 부분을 제거하고 -d,두 번째 필드는 그대로 둡니다.-f2

답변2

|데이터 구분 기호를 가정합니다 .

grep -Po '\brouter\.[^|]+?(\d{1,3}\.){3}\d{1,3}' data  | grep -Po '(?<=,).*'
  • 첫 번째 grep 결과:
    router.bec2,192.168.156.131
    router.ros78,192.168.159.125
    router.jed99,10.41.118.189
  • 두 번째 grep 결과:
    192.168.156.131
    192.168.159.125
    10.41.118.189

관련 정보