파일 내용 인쇄

파일 내용 인쇄

상위 폴더, 하위 폴더, 폴더와 하위 폴더 내에 파일 목록이 있습니다. 다음 명령줄을 사용하여 상위 폴더와 하위 폴더의 내용을 나열합니다.

tree > index.txt

"index.txt"의 출력은 다음과 같습니다.

.
|_ sdc
| |_ QA
| | |_  sp
| | | |_ data
| | | | | |_10507
| | | | | | |_01.txt 
| | | | | | |_02.txt           
| | | | | | |_03.zip

파일 중 하나가 zip 파일인 경우 파일 이름 옆에 각 파일의 첫 번째 줄과 두 번째 줄을 인쇄하는 방법가능합니까?다음과 같이 첫 번째 및 두 번째 줄과 함께 내용을 인쇄합니다.

. 
|_ sdc
| |_ QA
| | |_  sp
| | | |_ data
| | | | | |_10507
| | | | | | |_01.txt <first line> <secondline>
| | | | | | |_02.txt <first line> <secondline>
| | | | | | |_03.zip
| | | | | | | |_01.txt <first line> <secondline>
| | | | | | | |_02.txt <first line> <secondline>
| | | | | | | |_03.txt <first line> <secondline>

저는 sed -n '2p;d'모든 파일에서 원하는 줄을 인쇄하는 데 익숙합니다. 그러나 "tree" 명령줄과 나란히 사용하려면 어떻게 해야 합니까? 아니면 좋은 제안이 있습니까?

답변1

이 답변 끝에 있는 Python 스크립트는 원하는 작업을 정확하게 수행하지는 않지만 가까워야 합니다. 10999목차를 동일한 레벨에 표시하는 방법을 보여드리기 위해 목차를 추가했습니다 .
이 코드는 zip 파일 내의 하위 디렉터리를 잘 처리하지 못하므로 자신을 재귀적으로 호출하는 zip_recurse 루틴을 작성하는 것이 좋습니다.
코드는 Python 2.6.9, 2.7.9, 3.3.6 및 3.4.2에서 테스트되었습니다.

$ mkdir -p sdc/QA/SP/data/10507
$ echo -e '01 line 1\n01 line 2\n01 line 3' > sdc/QA/SP/data/10507/01.txt
$ echo -e '02 line 1\n02 line 2\n02 line 3' > sdc/QA/SP/data/10507/02.txt
$ echo -e '03 line 1\n03 line 2\n03 line 3' > sdc/QA/SP/data/10507/03.txt
$ mkdir -p sdc/QA/SP/data/10999
$ echo -e '04 line 1\n04 line 2\n04 line 3' > sdc/QA/SP/data/10999/04.txt
$ pushd sdc/QA/SP/data/10507/
$ zip 03.zip *.txt
$ rm 03.txt
$ popd
$ python test.py sdc
└── QA/
    └── SP/
        └── data/
            ├── 10507/
            │   ├── 01.txt: 01 line 1\n: 01 line 2\n
            │   ├── 02.txt: 02 line 1\n: 02 line 2\n
            │   └── 03.zip
            │       └── 01.txt: 01 line 1\n01 line 2\n
            │       └── 02.txt: 02 line 1\n02 line 2\n
            │       └── 03.txt: 03 line 1\n03 line 2\n
            └── 10999/
                └── 04.txt: 04 line 1\n: 04 line 2\n

test.py:

#! /usr/bin/env python
# coding: utf-8

from __future__ import with_statement

import sys
import os
from zipfile import ZipFile

class ListTree:
    # tree characters
    indent = 2

    def __init__(self, characters=None):
        """ characters should be None for graphical, "ASCII" for non
        graphical (+|`-) or a four letter sequence
        """
        if characters is None:
            self._char = u'├│└─'
        elif characters == 'ASCII':
            self._char = '+|`-'
        else:
            self._char == characters
        assert len(self._char) == 4

    def out(self, endmarkers, val, fp=None):
        # endmarkers is a list with the length of the list indicating
        # the depth and True values if at that depth this entry is the last one
        stream = fp if fp else sys.stdout
        s = u''
        for idx, n in enumerate(endmarkers):
            if idx == len(endmarkers) - 1:
                if n:
                    s += self._char[2] + self._char[3] * self.indent
                else:
                    s += self._char[0] + self._char[3] * self.indent
            else:  # not last one
                if n:
                    s += ' ' * (self.indent + 2)
                else:
                    s += self._char[1] + ' ' * (self.indent + 1)
        msg = u'{0} {1}\n'.format(s, val)
        if sys.version_info < (3,):
            msg = msg.encode('utf-8')
        stream.write(msg)


class WalkTree(object):
    def __init__(self, base_dir):
        lt = ListTree()
        old_dir = os.getcwd()
        os.chdir(base_dir)
        for n, x in self.recurse('.'):
            lt.out(n, x)
        os.chdir(old_dir)

    def recurse(self, path, prev=[]):
        # could use os.walk() but would have to combine the dir and file_name
        # lists, sort them and split apart, or keep the lists sorted separate
        # and check from which one to take the next entry
        lst = sorted(
            [x for x in os.listdir(path) if x and not x[0] == '.'])
        lidx = len(lst) - 1
        for idx, x in enumerate(lst):
            n = prev[:] + [idx == lidx]
            dpath = os.path.join(path, x)
            if os.path.isdir(dpath):
                x += '/'
                yield n, x
                for y in self.recurse(dpath, n):
                    yield y
            else:
                if os.path.splitext(x)[1] == '.txt':
                    with open(dpath) as fp:
                        for count in range(2):
                            x += ': ' + fp.readline().replace('\n', '\\n')
                elif os.path.splitext(x)[1] == '.zip':
                    yield (n, x)
                    n1 = n[:] + [idx == lidx]
                    # ZipFile in 2.6 doesn't have __enter__/__exit__ yet
                    zf = ZipFile(dpath)
                    for info in zf.infolist():
                        x1 = info.filename
                        if os.path.splitext(x1)[1] == '.txt':
                            data = zf.read(x1)
                            if sys.version_info >= (3,):
                                data = str(data, encoding='utf-8')
                            x1 += ': ' + '\\n'.join(data.split(
                                '\n', 2)[:2]) + '\\n'
                        yield(n1, x1)
                    zf.close()
                    return
                yield (n, x)

wt = WalkTree('.' if len(sys.argv) < 2 else sys.argv[1])

관련 정보