2015-04-15 4 views
0

Я пытаюсь прочитать файл и проанализировать его в bash. Мне нужно сделать dd конвертировать из EBCDIC в ASCII, затем цикл и читать X байт, обжигающе каждый X байт в виде строки в новый файл:Bash read & parse file - loop performance

#!/bin/bash 

# $1 = input file in EBCDIC 
# $2 = row length 
# $3 = output file 

# convert to ASCII and replace NUL (^@) with ' ' 
dd conv=ascii if=$1 | sed 's/\x0/ /g' > $3.tmp 
file=$(cat "$3.tmp") 
sIndex=1 
fIndex=$2 

# remove file 
rm $3 
echo "filesize: ${#file}"; 

# loop, retrieving each fixed-size record and appending to a file 
while true; do 
    # append record to file 
    echo "${file:sIndex:fIndex}" >> $3; 

    # break at end of file 
    if [ $fIndex -ge ${#file} ] 
    then  
     break; 
    fi 

    # increment index 
    sIndex=$((sIndex+fIndex)); 
done 

# remove tmp 
rm $3.tmp 

Любой способ сделать весь этот процесс быстрее?

+0

Не используйте временный файл. Просто передайте преобразование непосредственно в цикл while и используйте 'read' для чтения блоков фиксированного размера. Хотя это, вероятно, также будет медленным (вопрос в том, где все время в настоящее время занято). Вы знаете, какова медленная часть вашего скрипта? –

+0

Просто используя временный файл, поэтому я вижу, что возвращает 'dd'. Что касается 'read', файл не является точно линейным, как в, данные просто буквально как есть в файле (без разделителей и т. Д.). Не уверен, какая часть медленная, вероятно, из-за того, что файл имеет много записей для обработки. –

+0

'read' может читать по количеству символов, а также по строке и получать информацию профилирования всегда должен быть первым шагом при оптимизации чего-либо. –

ответ

1

Отвечая на мой вопрос. Ответ очень прост с использованием fold!

# $1 = ASCII input file 
# $2 = file record length (i.e. 100) 
# $3 = output file (non-delimited, row-separated file) 

# dd : convert from EBCDIC to ASCII 
# sed : replace NUL (^@) with space ' ' 
# fold : wrap input to specified width (record length) 

dd conv=ascii if=$1 | sed 's/\x0/ /g' | fold -$2 > $3