Я читал, что xargs был хорош для обработки вывода команды по одной строке за раз (и это так). У меня есть следующая строка в моем сценарии.

./gen-data | awk '{printf $2 " "; printf $1=$2=$3=""; gsub (" ", "", $0);if(length($0) == 0){ print "0000"} else{print $0}}' | xargs -t -n2 -P1 bash -c 'datatojson "$@"' _

Он производит правильный вывод, в этом нет сомнений. Тем не менее, gen-data выдает что-то вроде 1000 строк, и я действительно хотел бы, чтобы эта команда выполнялась после каждой строки, а не после 1000 строк (она явно останавливается, чтобы получить больше входных данных).

Вот как выглядит gen-data:

candump $interface &
while true; do
    while read p; do
        cansend $interface $(echo $p | awk 'NF>1{print $NF}');
    done < <(shuf $indoc)
done

(cansend отправляет данные на интерфейс, а candump читает с этого интерфейса и выводит их на экран, но держу пари, что это не слишком актуально). В любом случае, кажется, что candump непрерывно передает поток, но когда я передаю его в awk и xargs , он становится чанкованным. Это только потому, что я использовал shuf? Я бы подумал, что, поскольку он проходит через интерфейс и читается с другой стороны, он будет менее частым, чем предоставляет shuf.

1 ответ1

2

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

./gen-data | gawk '{printf $2 " "; printf $1=$2=$3=""; gsub (" ", "", $0);if(length($0) == 0){ print "0000"} else{print $0}; fflush(stdout)}' | stdbuf -o0 xargs -t -n2 -P1 bash -c 'datatojson "$@"' _

Помните о переходе с awk на gawk и использовании fflush . Вы также можете попробовать mawk -Winteractive . Также учтите, что я добавил stdbuf -o0 перед xargs. Вы также можете попробовать последнюю версию в начале ./gen-data

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .