ShellScript: grep + while + cut + awk в большом файле = очень медленно - PullRequest
3 голосов
/ 07 ноября 2011

Этот скрипт запущен в текстовом файле объемом 1,7 ГБ.

#!/bin/bash

File1=$1.tmp
File2=$1.modified

grep '^#' $1 > $File2
grep -v '#' $1 > $File1

while read line; do
        column_four=$(echo $line | cut -d " " -f4)
        final_line=$(echo $line | cut -d " " -f4-5)
        if [ "$column_four" == "0" ]; then
               beginning_line=$(echo $line | cut -d " " -f1-3)
               final_line=$(echo $line | cut -d " " -f4-5)
        else
               final_line=$(echo $line | cut -d " " -f1-2)
        fi
        linef=$(echo "$beginning_line $final_line")
        echo $linef | awk '{printf "%5.0f%12.4f%12.4f%5.0f%12.4f\n", $1, $2, $3, $4, $5}' >> $File2
done < $File1
rm -f $File1

Проблема: очень, очень медленно. Он создает новый файл со столбцами, расположенными со скоростью 200 КБ в минуту с Core2Duo. Как я могу сделать это быстрее?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 07 ноября 2011

Вы можете все это сделать в awk, насколько я вижу, что-то вроде

awk '/^#/ { print $0 >> "File2" ; getline}
     $0 ! ~ /#/ { if ( $4 == 0 ) { 
                  f1 = $1 ; f2 = $2 ; f3 = $3
                  printf("%5.0f%12.4f%12.4f%5.0f%12.4f\n", f1, f2, f3, $4, $5) >> "File2" }
                  else { printf("%5.0f%12.4f%12.4f%5.0f%12.4f\n", f1, f2, f3, $1, $2) >> "File2" }
                      } INPUTFILE
3 голосов
/ 07 ноября 2011

Я бы покончил с циклом и использовал бы один вызов awk:

awk '
{
    if ($4 == 0) {
       f1 = $1;
       f2 = $2;
       f3 = $3;
       f4 = $4;
       f5 = $5;
    } else {
       f4 = $1;
       f5 = $2;
    }
    printf ("%5.0f%12.4f%12.4f%5.0f%12.4f\n", f1, f2, f3, f4, f5);
}' < $File1 >> $File2

Таким образом, вы не вызываете awk, echo и cut несколько раз на строку входного файла и просто запускаете один awk процесс.

...