У меня есть несколько каталогов, которые содержат много файлов.Поскольку некоторые из них приближаются к 600-килобайтным файлам, они стали основной проблемой.Просто перечисление файлов постепенно становится основным узким местом в приложениях, обрабатывающих их.
Файлы называются так: id_date1_date2.gz Я решил разбить файлы на несколько меньших, в зависимости от первой части., "id".
Поскольку один и тот же идентификатор может отображаться в большом количестве файлов, и один и тот же идентификатор уже появляется в нескольких каталогах, мне нужно отслеживать, какие идентификаторы файлов были скопированы,и из чего реж.В противном случае я бы сделал то же самое, скопировав безумное количество раз или пропустив идентификатор X при копировании из dir Y, если он уже скопирован из dir Z.
Я написал сценарий для достижения этой цели.Была включена некоторая отладка
#!/bin/bash
find /marketdata -maxdepth 2 -type d | grep "[0-9]\.[0-9][0-9][0-9]$" | sort | #head -n2 | tail -n1 |
while read baseDir; do
cd $baseDir;
echo $baseDir > tmpFile;
find . -type f | grep -v "\.\/\." | #sort | head -n4 |
while read file; do
name=$(awk 'BEGIN {print substr("'"$file"'", 3,index("'"$file"'", "_")-3 )}');
dirkey=${baseDir//[\/,.]/_}"_"$name;
if [ "${copied[$dirkey]}" != "true" ]; then
echo "Copying $baseDir/$name with:";
echo mkdir -p $(sed 's/data/data4/' tmpFile)/$name;
#mkdir -p $(sed 's/data/data4/' tmpFile)/$name;
oldName=$baseDir/$name"_*";
echo cp $oldName "$(sed 's/data/data4/' tmpFile)/$name/";
#cp $oldName "$(sed 's/data/data4/' tmpFile)/$name/";
echo "Setting $dirkey to true";
copied[$dirkey]="true";
else
echo "$dirkey: ${copied[$dirkey]}"
sleep 1
fi
done;
rm tmpFile;
done
Проблема в том, что значение всех ключей в копировании, похоже, становится истинным с самого первого копирования, поэтому моя обработка массивов bash, вероятно, является проблемой здесь.
Некоторый прогресс: я пытался записать каждый ключ в файл, и после каждой итерации я вместо этого считывал этот файл в массив.Это, очевидно, действительно ужасно, но, похоже, это достигло моей цели.Может быть, это становится чрезвычайно медленным, так как я обработал несколько тысяч идентификаторов.Будет обновлено позже.
Для кого-то, кто может найти это в будущем, вот последний сценарий:
declare -A copied
find /marketdata -maxdepth 2 -type d -name "[0-9]\.[0-9][0-9][0-9]" | sort | #head -n3 | tail -n1 |
while read baseDir; do
cd $baseDir;
find . -type f | grep -v "\.\/\." | sort | #head -n100 |
while read file; do
length=$(expr index "$file" "_");
name=${file:2:$((length - 3))};
dirkey=${baseDir//[\/,.]/_}"_"$name;
if [ "${copied[$dirkey]}" != "true" ]; then
echo "Copying ${baseDir}/${name} to ${baseDir//data/data4}/$name";
mkdir -p "${baseDir//data/data4}/$name";
oldName="${baseDir}/${name}_*";
cp -n $oldName "${baseDir//data/data4}/${name}/";
copied[$dirkey]="true";
fi
done;
done
Нет awk, нет sed, лучше процитировано, нет записи временных файлов вдиск, меньше grep.Я не уверен, нужен ли взлом Dirkey сейчас, когда ассоциативный массив работает должным образом, и я не совсем понимаю, зачем мне нужен oldName var.