Bash - очень медленно извлекается соответствующая строка из файлов GZIP - PullRequest
2 голосов
/ 29 января 2020

Полный новичок в Bash. Пытаясь перебрать 1000 gzip файлов, может быть, GNU параллельное решение ??

#!/bin/bash
ctr=0
echo "file_name,symbol,record_count" > $1
dir="/data/myfolder"
for f in "$dir"/*.gz; do

  gunzip -c $f | while read line;
  do
    str=`echo $line | cut -d"|" -f1`
    if [ "$str" == "H" ]; then
      if [ $ctr -gt 0 ]; then
        echo "$f,$sym,$ctr" >> $1
      fi
      ctr=0
      sym=`echo $line | cut -d"|" -f3`
      echo $sym
    else
      ctr=$((ctr+1))
    fi
  done
done

Любая помощь для ускорения процесса будет принята с благодарностью !!!

Ответы [ 2 ]

0 голосов
/ 02 февраля 2020

Bash while read l oop, вероятно, является вашим главным узким местом здесь. Вызов нескольких внешних процессов для простого расщепления поля усугубит проблему. Вкратце,

while IFS="|" read -r first second third rest; do ...

использует встроенную в оболочку функцию разделения полей, но, возможно, вы все равно захотите преобразовать все это в простой скрипт Awk.

echo "file_name,symbol,record_count" > "$1"
for f in "/data/myfolder"/*.gz; do
  gunzip -c "$f" |
  awk -F "\|" -v f="$f" -v OFS="," '
    /H/ { if(ctr) print f, sym, ctr
      ctr=0; sym=$3;
     print sym >"/dev/stderr"
     next }
  { ++ctr }'
done >>"$1"

Это неопределенно предполагает, что печать одинокого sym только для диагностики. Надеемся, что нетрудно понять, как это можно изменить, если это неверное предположение.

0 голосов
/ 02 февраля 2020
#!/bin/bash
ctr=0
export ctr
echo "file_name,symbol,record_count" > $1
dir="/data/myfolder"
export dir

doit() {
  f="$1"
  gunzip -c $f | while read line;
  do
    str=`echo $line | cut -d"|" -f1`
    if [ "$str" == "H" ]; then
      if [ $ctr -gt 0 ]; then
        echo "$f,$sym,$ctr"
      fi
      ctr=0
      sym=`echo $line | cut -d"|" -f3`
      echo $sym >&2
    else
      ctr=$((ctr+1))
    fi
  done
}
export -f doit

parallel doit ::: *gz 2>&1 > $1 
...