다른 폴더의 모든 파일을 하나의 파일로 병합하고 줄 바꿈을 추가하는 방법

다른 폴더의 모든 파일을 하나의 파일로 병합하고 줄 바꿈을 추가하는 방법

폴더와 파일이 많이 있습니다. 이것이 제가 가진 구조입니다.

26-09-2016/CHANGELOG_20160926.TXT
26-09-2016/FILE_CHANGELOG_20160926.TXT
27-09-2016/CHANGELOG_20160927.TXT
27-09-2016/FILE_CHANGELOG_20160927.TXT

다음과 같은 출력이 필요합니다. 와 같은 이름을 가진 모든 파일은 CHANGELOG_*.TXT병합되어 처럼 하나의 파일에 별도의 새 줄을 추가해야 하며 CHANGELOG_20160926-20160930.TXT, 이름이 있는 모든 파일은 FILE_CHANGELOG_*.TXT처럼 하나의 파일에 병합되어 별도의 새 줄을 추가해야 합니다 FILE_CHANGELOG_20160926-20160930.TXT.

어떻게 해야 합니까?

답변1

언어 요구 사항을 지정하지 않았으므로 Python 3을 사용할 수 있습니다.

#/usr/bin/env python3

from glob import glob
from os.path import basename
import re

for prefix in ('CHANGELOG', 'FILE_CHANGELOG'):
    files = dict((int(re.split('[_.]', basename(f))[-2]), f)
                 for f in glob('*-*-*/%s_*.TXT' % prefix))
    out_file = '%s_%d-%d.TXT' % (prefix, min(files.keys()), max(files.keys()))

    with open(out_file, 'w') as f_out:
        for date in sorted(files.keys()):
            with open(files[date]) as f_in:
                for line in f_in:
                    f_out.write(line)
            f_out.write("\n")

glob기본적으로 및 를 사용하여 basename파일 이름을 나열하고 구문 분석하여 날짜별로 정렬합니다. 최소/최대 값은 출력 파일 이름을 만드는 데 사용되며 모든 파일은 여기에 순서대로 기록됩니다. 필요한 경우 실제 디렉토리 구조에 맞게 패턴을 조정하는 것을 잊지 마십시오. 그런 다음 다음 chmod을 실행하십시오.

$ chmod +x script.py
$ ./script.py

답변2

솔루션TXR:

먼저 경로 이름의 예제 목록과 이라는 입력 파일이 있다고 가정하고 이를 텍스트 처리 작업으로 처리해 보겠습니다 paths. 파일 그룹을 함께 모아 필요한 출력 파일을 생성하는 paths셸 명령으로 변환합니다 .cat

@(do
   (defstruct file-info nil
     full-name
     root-name
     date-key
     (:method equal (self) self.date-key)))
@(collect :vars (files))
@  (all)
@dd-@mm-@yyyy/@*{name}_@yyyy@[email protected]
@  (and)
@path
@  (end)
@  (bind files @(new file-info full-name path root-name name
                     date-key ^(,yyyy ,mm ,dd)))
@(end)
@(do
   (let ((h (group-by (usl root-name) files :equal-based)))
     [hash-update h sort]
     (dohash (name flist h)
       (let ((start (find-min flist))
             (end (find-max flist))
             (paths (mapcar (usl full-name) flist)))
         (put-line `cat @{paths " "} >\ \
                    @{start.root-name}_@{start.date-key ""}- \
                    @{end.date-key ""}.TXT`)))))

달리다:

$ txr catfiles.txr paths
cat 26-09-2016/CHANGELOG_20160926.TXT 27-09-2016/CHANGELOG_20160927.TXT > CHANGELOG_20160926-20160927.TXT
cat 26-09-2016/FILE_CHANGELOG_20160926.TXT 27-09-2016/FILE_CHANGELOG_20160927.TXT > FILE_CHANGELOG_20160926-20160927.TXT

실제 경로에서 작업하고 cat명령을 수행하려면 간단한 수정이 필요합니다.

@(do
   (defstruct file-info nil
     full-name
     root-name
     date-key
     (:method equal (self) self.date-key)))
@(next :list (glob "*/*.TXT"))
@(collect :vars (files))
@  (all)
@dd-@mm-@yyyy/@*{name}_@yyyy@[email protected]
@  (and)
@path
@  (end)
@  (bind files @(new file-info full-name path root-name name
                     date-key ^(,yyyy ,mm ,dd)))
@(end)
@(do
   (let ((h (group-by (usl root-name) files :equal-based)))
     [hash-update h sort]
     (dohash (name flist h)
       (let ((start (find-min flist))
             (end (find-max flist))
             (paths (mapcar (usl full-name) flist)))
         (sh `cat @{paths " "} >\ \
              @{start.root-name}_@{start.date-key ""}- \
              @{end.date-key ""}.TXT`)))))

유일한 변경 사항은 @(next :list (glob "*/*.TXT"))파일 시스템에서 글로브된 경로 목록에 대한 입력 검색을 리디렉션하기 위해 a를 추가하고 명령을 실행 하기 위해 put-string에서 로 스위치를 추가한 것입니다 .shcat

파일 목록이 매우 클 수 있는 경우 OS 명령/argv 전달 제한이 발생합니다. 단일 명령으로 이를 분류할 수 없습니다.

이에 대한 가능한 수정 방법은 코드의 마지막 부분을 다음과 같이 변경하는 것입니다.

@(do
   (let ((h (group-by (usl root-name) files :equal-based)))
     (hash-update h (op sort))
     (dohash (name flist h)
       (let* ((start (find-min flist))
              (end (find-max flist))
              (paths (mapcar (usl full-name) flist))
              (target `@{start.root-name}_@{start.date-key ""}- \
                       @{end.date-key ""}.TXT`))
         (sh `> @target`)
         (each ((group-of-ten (tuples 10 paths)))
           (sh `cat @{group-of-ten " "} >> @target`))))))

즉, 각 파일에 대해 해당 > file파일이 존재하고 0으로 잘리는지 확인하는 데 사용됩니다. 그런 다음 cat ... >> file10개 그룹으로 로그를 추가하는 데 사용합니다 .

관련 정보