советы с awk с изменением параметров - PullRequest
0 голосов
/ 28 ноября 2011

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

for ff in `seq 3 $nlpN`;
do    
    npc1[$ff]=`awk 'NR=='$ff' {print $1}' p_walls.raw`;
    echo ${npc1[$ff]};
    npc2[$ff]=`awk 'NR=='$ff' {print $2}' p_walls.raw`;
    npc3[$ff]=`awk 'NR=='$ff' {print $3}' p_walls.raw`;
    npRs[$ff]=`awk 'NR=='$ff' {print $4}' p_walls.raw`;
    echo $ff
done

как видите, я вызываю awk несколько раз. Есть ли более быстрый способ сделать это, например, вызвать awk один раз и выполнить назначения с измененными параметрами?

Большое спасибо заранее!

вход выглядит так: ... 3,76023 0,79528 0,307771 8729,82

3,76024 0,814664 0,307849 8650,2

3,76026 0,845679 0,307978 8802,97

3,76025 0,826293 0,307897 8690,43

3,76017 0,65959 0,30722 8936,07 ...

я ищу что-то вроде:

TY

Ответы [ 2 ]

0 голосов
/ 06 декабря 2011

Выполнить awk один раз и обработать вывод на каждой итерации отдельно.

awk "(NR > 3 && NR <= $nlpN)"' { print NR, $1, $2, $3, $4 }' p_walls.raw |
while read ff c1 c2 c3 Rs
do    
    npc1[$ff]=$c1
    echo ${npc1[$ff]};
    npc2[$ff]=$c2
    npc3[$ff]=$c3
    npRs[$ff]=$Rs
    echo $ff
done
0 голосов
/ 28 ноября 2011

Это выглядит довольно неэффективно.Как написано, awk обрабатывает входной файл полностью четыре раза с каждым проходом цикла.Я также почти уверен, что cut совершенно не нужен, если у вас не установлена ​​переменная окружения FS.Следующая команда заменит несколько прогонов awk одним проходом по файлу данных, который останавливается после того, как он находит строку.Затем вы можете использовать cut для извлечения отдельных полей.

for ff in `seq 3 $nlpN`
do
    data=`awk 'NR=='$ff' { print $1, $2, $3, $4; exit }' p_walls.raw`
    npc1[$ff]=`echo "$data" | cut -f1 -d ' '`
    echo ${npc1[$ff]}
    npc2[$ff]=`echo "$data" | cut -f2 -d ' '`
    npc3[$ff]=`echo "$data" | cut -f3 -d ' '`
    npRs[$ff]=`echo "$data" | cut -f4 -d ' '`
    echo $ff
done

Обратите внимание, что я добавил оператор exit, чтобы awk завершал работу после обработки строки.Это предотвращает чтение всего файла на каждом проходе.Если все, что вам нужно сделать, это извлечь одну строку из файла, то вы можете вместо этого использовать sed, поскольку (ИМХО) скрипт легче читать, и он кажется немного быстрее для больших файлов.Следующее выражение sed эквивалентно строке awk:

data=`sed -n -e "$ff p" -e "$ff q" p_walls.raw`

-n предписывает sed выводить только строки, выбранные сценарием .В этом случае сценарий поставляется в виде двух -e параметров.Каждый адрес является адресом, за которым следует команда обработки.Несколько команд разделены символами новой строки в сценариях sed, но они также могут быть заданы несколькими параметрами -e с одним и тем же адресом.Собрав все это вместе, выражение 42 p говорит sed выбрать строку 42 и выполнить команду p, которая печатает выбранное пространство шаблона (42-я строка).Команда 42 q сообщает утилите выйти после обработки 42-й строки.Итак, наше выражение sed читает первые $ff th строки из "p_walls.raw", печатает $ff th одну и выходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...