폴더와 파일이 너무 많아요. 이것이 제 구조입니다.
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"))
입력 스캔을 파일 시스템에서 얻은 경로 목록으로 리디렉션하고 명령에서 실행 으로put-string
전환하는 것입니다 .sh
cat
파일 목록이 매우 클 수 있는 경우 운영 체제 명령/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 ... >> file
10개의 그룹으로 로그를 추가하는 데 사용됩니다 .