2013-03-22 4 views
1

Мне нужно сравнить набор переменных из файла 'tmpcsv2' с переменными в 'uniq_id', я подробно описываю файлы ниже.Простой способ сравнения переменных

tmpcsv2 -> Этот файл обновляется с помощью другого скрипта 'script1', и каждый запуск 'script1' обновляет (не добавляет) новые переменные в 'tmpcsv2'. Нет. переменных может быть 1 и может доходить до 200.

eg: 
2042344352 
2470697747 
2635527510 
3667769962 

Uniq-ид -> Это фиксированный набор переменных (около 100K в нет.)

(Business Name,Job ID,Job Size) 
biz,1000036446,225210640 
biz,100006309,6710840 
biz,1000069211,2084019000 
biz,1000118720,34194040 
biz,1000150241,212322636 

Я использую «для 'loops +' if ', чтобы сравнить их, как показано ниже, есть ли более простой или быстрый (менее удачный) способ сделать это? Когда я запускаю это, для вывода результатов требуется очень много времени. Команды печати предназначены только для тестирования и будут удалены позже!

****Part of a bigger script**** 
amt=0 
mjc=0 
for jbid in `cat tmpcsv2` #Pick ID for match & calculation 
do 
    printf "Checking ID $jbid\n" >> Acsv3.tmp 
    for bsid in `cat uniq_id` #Matching jobs & size calulation 
    do 
     ckid=`echo $bsid | cut -d "," -f2` #ckid is the ID to check 
     jbsiz=`echo $bsid | cut -d "," -f3` #size of the ID 
     if [ $jbid == $ckid ] 
     then 
      printf "Matched at $ckid\n" #Print on Match found 
      printf "Valid -> $jbid\n" >> Bcsv3.tmp 
      ((mjc++)) #Increment Matched Job Count 
      amt=$((amt+jbsiz)) #Add size of matched jobs 
      break 
     else 
      printf "No Match at $cksid\n" #No matches 
     fi 
    done 
    printf "Check for ID $jbid done\n" >> Acsv3.tmp 
    printf "Matched $mjc jobs with combined size of $amt\n" >> Acsv3.tmp 
done 
****End of Comparision**** 
+0

Каков точный формат ввода? Обратите внимание, что вы фактически не используете переменную 'jbid' в любом месте, кроме вывода, поэтому сами сравнения даже не включают этот файл. – ormaaj

+0

@ormaaj, я отредактировал сценарий, чтобы показать использование «jbid», я использую его для сравнения переменных. – Marcos

ответ

1

Скорлупа - это неправильный инструмент для хрустания этих данных, но это выполнимо. Самая основная ошибка здесь - reading lines with for. Эффективность может быть значительно улучшена, если не повторить открытие файлов на каждой итерации.

function main { 
    # Variables used elsewhere should be initialized there, not localized here. 
    typeset amt=0 mjc=0 jbid ckid jbsiz 

    while IFS= read -r jbid; do 
     printf 'Checking ID %s\n' "$jbid" >&3 
     while IFS=, read -r _ ckid jbsiz _; do 
      case $jbsiz in 
       *[^[:digit:]]*|'') 
        # validation is important for subsequent arithmetic. 
        return 1 
        ;; 
       "$ckid") # Assuming "cksid" was a typo. Replace if not. 
        printf 'Matched at %s\n' "$ckid" 
        printf 'Valid -> %s\n' "$jbid" >&4 
        ((mjc++, amt += jbsiz)) 
        break 
        ;; 
       *) 
        printf 'No match at %s\n' "$ckid" 
      esac 
     done <uniqid 
     { 
      printf 'Check for ID %s done\n' "$jbid" 
      printf 'Matched %s jobs with combined size of %s\n' "$mjc" "$amt" 
     } >&3 
    done <tmpcsv2 3>>Acsv3.tmp 4>>Bcsv3.tmp 
} 

Наконец, эквивалентный скрипт awk значительно превзойдет этот скрипт Bash, как и любой другой язык. Вы также можете получить большую производительность из Bash, используя mapfile вместо цикла чтения, но эта вложенная логика цикла чтения немного неаккуратная для эмуляции с использованием обратных вызовов mapfile.

+0

Это оболочка? и может ли кадр awk с аналогичной логикой? – Marcos

+0

Это оболочка, использующая немного синтаксиса bash/ksh. Надеюсь, это близко к тому, что вы хотите. Я мог бы сделать awk, но кто-то другой, вероятно, может сделать лучшую работу, чем я ... Мне обычно приходится RTFM. – ormaaj

0

Я придумал это, не уверен, что это можно укоротить, но он уверен, что он работает быстрее! Любая помощь будет высоко ценится !

************ 
while read -r line #File read start 
do 
IFS=$"," 
val=$line 
amt=0 
mjc=0 
cjc=0 
for lsid in $val 
do 
    cksid=`echo $lsid | sed -e 's/*//g' -e 's/"//g'` 
    printf "Checking for $cksid\n" 
    ((cjc++)) #Count of jobs to check 
    prsnt=`grep -w $cksid uniq_id` 
    if [ $? -eq 0 ] 
    then 
     printf "Valid -> $cksid\n" 
     jbsiz=`grep -w $prsnt | cut -d, -f2` 
     ((mjc++, amt += jbsiz)) 
     break 
    else 
     printf "No Data for $cksid\n" 
    fi 

done 
done < tmpcsv2 
*********** 
+0

У меня почти был вкус победы с этим сценарием ... но я использовал «grep», и это не вызывало у меня горя! grep делает все три значения одинаковыми! -> 448742, 3660'448742 ', 115'448742'464 – Marcos

+0

Я внес некоторые изменения в свой файл ввода, и теперь grep отлично работает! Может ли кто-нибудь проверить и сообщить мне, является ли это хорошим методом для сравнения? – Marcos

Смежные вопросы