Solução em TXR :
Primeiro, vamos tratar isso como uma tarefa de processamento de texto, supondo que tenhamos a lista de exemplos de nomes de caminho em um arquivo de entrada chamado paths
. Transformamos paths
em comandos shell que cat
dos grupos de arquivos juntos e produzimos os arquivos de saída necessários:
@(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')))))
Executar:
$ 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
Para trabalhar em caminhos reais e executar os comandos cat
, é necessário fazer modificações simples:
@(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')))))
As únicas mudanças são a adição de um @(next :list (glob "*/*.TXT"))
para redirecionar a varredura de entrada através de uma lista de caminhos globbed do sistema de arquivos, e uma mudança de put-string
para sh
para ter os comandos cat
executados. / p>
Se as listas de arquivos puderem ser muito grandes, nos encontraremos nos limites de passagem do comando / argv do SO: não podemos cat-los em um único comando.
Uma possível correção para isso é alterar a última parte do código para:
@(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'))))))
Ou seja. para cada arquivo, use > file
para garantir que ele exista e seja truncado para zero. Em seguida, use cat ... >> file
para anexar os logs a ele, em grupos de dez.