Можно ли сделать это быстрее (прочитать файл, заменить [sed], написать новый файл) - PullRequest
2 голосов
/ 12 сентября 2010

Я использую этот фрагмент кода в своем bash-скрипте, чтобы прочитать файл, содержащий несколько шестнадцатеричных строк, выполнить некоторую подстановку и затем записать его в новый файл. Требуется около 30 минут для примерно 300 Мб.
Мне интересно, можно ли это сделать быстрее?

sed 's,[0-9A-Z]\{2\},\\\\x&,g' ${in_file} | while read line; do
 printf "%b" ${line} >> ${out_file}
 printf '\000\000' >> ${out_file}
done

Обновление:

Я провел некоторое тестирование и получил следующие результаты:

Победитель:


sed 's,[0-9A-Z]\{2\},\\\\x&,g' ${in_file} | while read line; do
    printf "%b" ${line} >> ${out_file}
    printf '\000\000' >> ${out_file}
done

реальный 44m27.021s
пользователь 29m17.640s
sys 15m1.070s


sed 's,[0-9A-Z]\{2\},\\\\x&,g' ${in_file} | while read line; do
    printf '%b\000\000' ${line} 
done >> ${out_file}

реальный 18m50.288s
пользователь 8m46.400s
sys 10m10.170s


export LANG=C
sed 's/$/0000/' ${in_file} | xxd -r -ps >> ${out_file}

реальный 0m31.528s
пользователь 0m1.850s
sys 0m29.450s


Ответы [ 4 ]

4 голосов
/ 12 сентября 2010

Вам нужна команда xxd, которая поставляется с Vim.

export LANG=C
sed 's/$/0000/' ${in_file} | xxd -r -ps > ${out_file}
3 голосов
/ 12 сентября 2010

Это медленно из-за цикла в bash.Если вы можете использовать sed / awk / perl / etc для выполнения цикла, он будет намного быстрее.Я не вижу, как вы можете сделать это в sed или awk, хотя.Это, вероятно, довольно легко для Perl, но я не знаю достаточно Perl, чтобы ответить на этот вопрос для вас.

По крайней мере, вы сможете сэкономить немного времени путем рефакторинга того, что вам нужно:

sed 's,[0-9A-Z]\{2\},\\\\x&,g' ${in_file} | while read line; do
 printf '%b\000\000' ${line} 
done >> ${out_file}

По крайней мере, так вы запускаете printf один раз за итерацию и открываете / закрываете $ {out_file} только один раз.

2 голосов
/ 12 сентября 2010

Переключиться на полноценный язык программирования?Вот один вкладыш Ruby:

ruby -ne 'print "#{$_.chomp.gsub(/[0-9A-F]{2}/) { |s| s.to_i(16).chr }}\x00\x00"'
0 голосов
/ 12 сентября 2010

если у вас есть Python и предполагается, что данные просты

$ cat file
99
AB

Сценарий:

o=open("outfile","w")
for line in open("file"):
    s=chr(int(line.rstrip(),16))+chr(000)+chr(000)
    o.write(s)
o.close()
...