Вероятно, есть более простой способ сделать это в 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')";
}
Ваша ошибка заключается в попытке 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)
для сопоставления с одним из вложенных шаблонов или строк.