Как добавить содержимое нескольких файлов в несколько файлов по группам - PullRequest
0 голосов
/ 17 ноября 2018

Мне нужно вывести много разных групповых текстовых файлов, объединяя содержимое только файлов той же группы. Порядок содержимого файлов, которые должны быть объединены в каждой группе, является критическим и должен поддерживаться, как показано. В частности, у меня есть эти файлы (пример игрушечного размера для dev; огромный размер для реального):

$ find . -name "*.doc" | sort -k1 -k2 -t'.'
./403and780.bunk_2018-02-09.doc
./immortalis.bunk_2018-03-01.doc
./KryptoFreak405.bunk_2018-03-01.doc
./kygiacomo.bunk_2018-02-09.doc
./Mimi108.bunk_2018-03-02.doc
./namohysip.bunk_2018-02-09.doc
./scarletcrawford.bunk_2018-02-10.doc
./SDsc0rch.bunk_2018-02-09.doc
./SDsc0rch.bunk_2018-02-10.doc
./SDsc0rch.bunk_2018-03-02.doc
./shitpostlord4321.bunk_2018-02-09.doc
./thwinks.bunk_2018-03-02.doc

В основном я хочу, чтобы содержимое 3 файлов SDsc0rch было помещено в 1 групповой файл в указанном порядке. Существует только 1 файл 403and780, который аналогичным образом попадает в его 1 файл группы и т. Д. Значение группы, например 403and780, будет служить именем вновь созданного файла.

Итак, вот мой лучший код. Я посмотрел на awk и datamash, но не могу получить от них помощи.

$ find . -name "*.doc" | sort -k1 -k2 -t'.' | xargs cat #(or paste)

$ paste --serial SDsc0rch.bunk_2018-02-09.doc SDsc0rch.bunk_2018-02-10.doc SDsc0rch.bunk_2018-03-02.doc > SDsc0rch.doc

Я вручную создал симулированную команду вставки, которая работает только для одной конкретной группы (SDsc0rch). Таким образом, приведенный выше код неверен, но что-то вроде xargs cat или xargs paste может отлавливать имена файлов, генерируемые для каждой группы, если бы я мог получать только групповые выбросы от какой-то программы Gnu.

Мне действительно нужны групповые файлы, генерируемые по группам, для cat или paste, а затем делайте это для всех найденных групп.

Из-за огромного количества файлов, на диске более 40 ГБ, и это всего лишь пример разработки, я бы предпочел не пытаться загрузить все содержимое файла в рабочую память перед записью файлов группы. У меня нет 40 ГБ оперативной памяти. Вместо этого я предпочел бы обрабатывать только группу за раз: сопоставить только группу файлов, которую определила моя команда сортировки, а затем перейти к следующей группе.

Спасибо за идеи.

1 Ответ

0 голосов
/ 18 ноября 2018

Как насчет чего-то вроде:

#!/bin/bash

while read -r group; do
    ifs_bak=$IFS
    IFS=$'\n'
    declare -a files=( $(find . -name "$group*.doc" | sort -k2 -t".") )
    IFS=$ifs_bak
    cat "${files[@]}" > "${group}.doc"      # or "paste" as you like
done < <(find . -name "*.doc" -print0 | while read -r -d "" file; do
    tmp=$(basename "$file"); echo "${tmp%%.*}"
done | sort | uniq)

Пояснения:

Задание можно разделить на два этапа:

  1. доизвлечь имя группы из имен файлов
  2. , чтобы найти файлы, которые принадлежат каждой группе

1-й шаг выполняется во фрагменте:

find . -name "*.doc" -print0 | while read -r -d "" file; do
    tmp=$(basename "$file"); echo "${tmp%%.*}"
done | sort | uniq

, который выводит:

403and780
KryptoFreak405
Mimi108
SDsc0rch
immortalis
kygiacomo
namohysip
scarletcrawford
shitpostlord4321
thwinks
  • -print0 необходимо для обработки имени файла, которое может содержать пробелы.
  • Следующая строка tmp=$(basename "$file"); echo "${tmp%%.*}" извлекает имя группы, удаляя dirname и подстроку после "«.в имени файла.
  • sort и uniq очищает имена групп, удаляя избыточные имена.

Затем вышеприведенный вывод передается в цикл while как2-й шаг:

  • IFS временно назначается новой строке для создания массива из выходных данных find
  • Тогда массив files содержит имена файлов, которые принадлежатк обрабатываемой в данный момент группе.

Рекомендуется предварительно протестировать с небольшим подмножеством файлов.Кроме того, было бы лучше рассмотреть, где хранить объединенные файлы.Каталог, в котором находятся существующие файлы, может оказаться неподходящим.
Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...