Объединение файлов построчно в каталоге в соответствии с их типом

Вероятно, есть более простой способ сделать это в R или в виде сценария оболочки, но вы можете сделать это довольно легко и на Perl. Просто вставьте это в текстовый файл (, назовите его foo.pl )и запустите как "perl foo.pl"

my @files = sort glob("~/Downloads/*.XPT");
foreach my $file (@files)
   {
   ( my $csvfile = $file ) =~ s/\.XPT/\.csv/g;
   system "R;library('foreign');data=read.xport('~/Downloads/$file');write.csv(data, file ='~/Downloads/$csvfile')";
   }

1
05.10.2021, 09:32
1 ответ

Ваша ошибка заключается в попытке catфайла, на который ссылается $file, после перехода в другой каталог, где этот файл недоступен.

Кажется, вы проверяете имена файлов и классифицируете их на основе этого.

Код можно упростить.

#!/bin/bash

shopt -s nullglob

declare -A envdir

months=( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec )
envdir=( [dev]=Env1 [prod]=Env2 )

for name in *.log; do
        IFS='.-' read -r env type year month day suffix <<<"$name"

        m=${months[(10#$month) - 1]}
        w="Wk$(( 1 + (10#$day)/7 ))"

        if [ -z "$m" ] || [ ! -d "${envdir[$env]}" ]; then
                echo 'Nothing to do'
                continue
        fi

        cat -- "$name" >>"${envdir[$env]}/${m}_${type^}_$w.log"
done

В приведенном выше примере используется тот факт, что имена каталогов для типов уже являются частью имен файлов. Нам просто нужно увеличить -регистр начальных символов, что мы и делаем с ${type^}. Различные части имени файла считываются в переменные с помощью read.

Мы выбираем название месяца из массива на основе номера месяца, а не просматриваем длинный список if, then, else. Номер недели вычисляется на основе дня. Используемый каталог среды хранится в ассоциативном массиве envdir.

Нам не нужно cdникуда.

Параметр оболочки nullglobприводит к полному исчезновению шаблона подстановки, если он ничему не соответствует. Без nullglob,шаблон *.logбудет назначен на name, и будет иметь место по крайней мере одна итерация цикла.

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

#!/bin/bash

shopt -s nullglob extglob

declare -A envdir

months=( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec )
envdir=( [dev]=Env1 [prod]=Env2 )

for name in @(dev|prod).@(critical|error)-????-??-??.log; do
        # as before
done

Обратите внимание на добавление опции оболочки extglob. Это позволяет нам написатьksh-как расширенный шаблон подстановки, чтобы соответствовать конкретным именам, которые мы хотим посмотреть. В частности, это позволяет нам использовать @(pattern|pattern|pattern)для сопоставления с одним из вложенных шаблонов или строк.

2
05.10.2021, 10:34

Теги

Похожие вопросы