grep 출력에서 ​​xml 문서를 작성하는 방법

grep 출력에서 ​​xml 문서를 작성하는 방법

find | grep작업 결과를 구조화된 XML 문서로 변환 하고 싶습니다 . 여기서 파일 항목에는 파일 이름, 발생 횟수, 줄 번호 및 줄 내용이 포함됩니다. Linux는 출력 형식을 지정하는 도구를 제공합니까, 아니면 코드를 직접 작성해야 합니까?

답변1

그래서 저는 Python으로 시도해 보았고 여러분이 원하는 것을 수행하는 간단한 스크립트를 생각해낸 것 같습니다. 여기있어:

#!/usr/bin/env python2
# -*- coding: ascii -*-
"""pathlist2xml.py

Takes a list of file-system paths and
generates an XML representation of the
corresponding file-system hierarchy.
"""

import sys
from lxml.etree import Element, SubElement, fromstring, tostring, XMLParser
from xml.sax.saxutils import escape, unescape
from os.path import join, isdir
from posix import lstat
import fileinput

def insert_path(xmlroot, path):
    """Updates an XML element `xmlroot` and adds the
    child elements that represent the path `path`."""

    # Initialize a node cursor to start at the root node
    xmlcursor = xmlroot

    # Keep track of the relative path
    fullpath = ''

    # Iterate through the components of the path
    for path_component in path.split('/'):

        # Update the path
        fullpath = join(fullpath, path_component)

        # UTF and XML encode the strings
        fullpath_encoded = escape(fullpath.encode('string-escape'))
        path_component_encoded = escape(path_component.encode('string-escape'))

        # Check to see if the component if already represented by a node
        xmlnodes = xmlcursor.xpath("./*[@name='%s']" % path_component_encoded)

        # If the node exists, update the cursor
        if xmlnodes:
            xmlcursor = xmlnodes[0]

        # If the node doesn't exists, create it
        else:

            # Create the node
            if isdir(fullpath):
                xmlcursor = SubElement(xmlcursor, "directory")
            else:
                xmlcursor = SubElement(xmlcursor, "file")

            # (Optional) Add some file-attributes
            # xmlcursor.set('name', path_component)
            xmlcursor.set('name', path_component_encoded)
            xmlcursor.set('path', fullpath_encoded)
            xmlcursor.set('inode', str(lstat(fullpath).st_ino))

    # Return the modified root element (for convenience - not necessary)
    return(xmlroot)

def paths_to_xml(pathlist):
    """ Takes a list of file-system paths and generates an XML
    representation of the corresponding file-system hierarchy.
    """

    xmlroot = Element('root')

    for path in pathlist:
        insert_path(xmlroot, path.strip().strip('/'))

    return(xmlroot)

# Read a list of file paths standard input or from a list of files
if __name__ == "__main__":

    # Get the XML document
    xmlroot = paths_to_xml(fileinput.input())

    # Display the generated XML document
    print(tostring(xmlroot, pretty_print=True))

다음은 실제로 어떻게 작동하는지 보여주는 작은 예제 세션입니다. 먼저 몇 가지 디렉터리와 파일을 만들었습니다.

mkdir -p /tmp/xmltest
cd /tmp/xmltest
touch file1
touch file2
mkdir dir1
touch dir1/file3
touch dir1/file4
mkdir dir2
mkdir dir2/dir3
touch dir2/dir3/file5

이 하위 계층 구조는 다음과 같습니다 tree.

.
├── dir1
│   ├── file3
│   └── file4
├── dir2
│   └── dir3
│       └── file5
├── file1
└── file2

다음은 다음 출력으로 스크립트를 호출하는 방법의 예입니다 find.

find . | pathlist2xml.py

결과 XML 출력은 다음과 같습니다.

<root>
  <directory name="." path="." inode="3587802">
    <directory name="dir1" path="./dir1" inode="3587817">
      <file name="file3" path="./dir1/file3" inode="3587818"/>
      <file name="file4" path="./dir1/file4" inode="3587819"/>
    </directory>
    <directory name="dir2" path="./dir2" inode="3587820">
      <directory name="dir3" path="./dir2/dir3" inode="3587821">
        <file name="file5" path="./dir2/dir3/file5" inode="3587822"/>
      </directory>
    </directory>
    <file name="file1" path="./file1" inode="3587815"/>
    <file name="file2" path="./file2" inode="3587816"/>
  </directory>
</root>

find다음은 다음과 결합된 두 번째 예입니다 grep.

find . | grep dir2 | pathlist2xml.py

이것은 두 번째 예제의 출력입니다.

<root>
  <directory name="." path="." inode="3587802">
    <directory name="dir2" path="./dir2" inode="3587820">
      <directory name="dir3" path="./dir2/dir3" inode="3587821">
        <file name="file5" path="./dir2/dir3/file5" inode="3587822"/>
      </directory>
    </directory>
  </directory>
</root>

관련 정보