Решение в TXR :
Во-первых, давайте рассмотрим это как задачу обработки текста, предполагая, что у нас есть пример списка имен путей a входной файл с именем paths
. Мы преобразовываем пути
в команды оболочки, которые объединяют
группы файлов и создают требуемые выходные файлы:
@(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@mm@dd.TXT
@ (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@mm@dd.TXT
@ (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
, чтобы убедиться, что он существует и обрезается до нуля. Затем используйте cat ... >> file
, чтобы добавить к нему журналы группами по десять.
Код 0x01
— это Control-A, который является командным символом по умолчанию на экране, поэтому, когда вы выполняете control + ← дважды у вас есть привязка действия по умолчанию other, т.е. другое окно, отсюда и сообщение.
Вы можете изменить командный символ на другой, например, Control-b при запуске экрана:
screen -e^Bb
или вы можете поместить в свой ~/.screenrc
строку
escape ^Bb
Вы установили Ctrl+Left для отправки символа ^A (Ctrl+A). Это тот же символ, который отправляет Ctrl+A, а ^A является префиксным символом по умолчанию для привязок клавиш экрана.
bindkey "^[[5D" prev
в настройках экрана бесполезен по двум причинам. Во-первых, это определяет, что происходит, когда экран получает эту escape-последовательность после символа префикса , то есть после ^A. Во-вторых, ^[[5D
— это то, что некоторые терминалы отправляют для Ctrl+Left, но вы перенастроили свой терминал для отправки чего-то другого (^A).
Вместо отправки Ctrl+Left ^A заставьте отправить ^[[1~
или ^[OH
( где ^[
— escape-символ). Аналогичным образом заставьте Ctrl+Right отправить ^[4~
или ^[OF
вместо ^E. Это управляющие последовательности, обычно посылаемые клавишами Home и End.