Хранение вывода awk в массиве и печать его в файл с разделителями-запятыми

Согласно исходному коду , невозможно сделайте это с помощью top.

Тем не менее, top имеет параметр -p , который позволяет указать ему, что нужно отслеживать только определенные PID. К сожалению, этот параметр также ограничен 20 параметрами, и в ядре легко может быть запущено более 20 процессов.

Я создал двухстрочный сценарий, чтобы проверить это:

kprocs=$(ls -l /proc/*/exe | grep -v " -> " | cut -d "/" -f 3)
top -c -p $(echo ${kprocs} | sed 's/ /,/g')

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

0
28.03.2019, 06:29
1 ответ

В первый раз в вашем цикле вы устанавливаете energy=( $(awk...) ), и вывод из awkсостоит из нескольких строк, каждая из которых содержит одно число и заканчивается символом новой строки, как это всегда делают строки в Unix. Подстановка команд $(... )удаляет завершающую новую строку (с ), а когда она не заключена в двойные -кавычки, то разбивает результат на «слова» в любой из пробелов на новой строке (у вас есть новые строки ), и, наконец, если какое-либо слово является «шаблоном» (, содержащим ?*[..]), которое соответствует любому имени файла (s ), оно заменяется этими именами файлов (s )как отдельные «слова» (у вас нет таких шаблонов 'glob' ). Назначение массива energy=(... )затем сохраняет эти слова как элементы массива.

Во второй раз через IFS устанавливается запятая. Теперь, когда $(... )пытается разбить на слова, он использует (только запятую )и в выводе awk нет запятых, поэтому весь вывод (, включая новые строки ), остается как одно слово и присваивается массиву как один элемент.

Вам необходимо возвращать IFS для каждой итерации. Кроме того, вам необходимо установить стандартное значение IFS или, по крайней мере, значение, содержащее новую строку, в записи этого скрипта. OTOH откат IFS непосредственно перед выходом из скрипта в основном бесполезен; сценарий обычно запускается в отдельном процессе оболочки, и любые настройки переменных или другие изменения процесса -, сделанные сценарием, отбрасываются при выходе из сценария.

Или , вместо изменения IFS и явного возврата, вы можете сделать это в подоболочке , чтобы изменение отбрасывалось после завершения подоболочки. Синтаксис оболочки для подоболочки: также круглые скобки, на этот раз сами по себе:

( IFS=","; echo "${energy[*]};" >> $energies )
# you don't actually need to quote, here but 
# it's a good habit for string literals in general

Также в целом printfбезопаснее, чем echo, потому что в зависимости от используемой оболочки и/или системы echoможет исказить некоторые строковые значения. Однако значения, которые вы здесь --ограничены десятичными числами --, безопасны для echo.

Для bash есть еще одна возможность обрабатывать данные как одну строку, а не как массив:

energy=$( awk '/Total energy/{print $3}' output )
# command substitution strips the last newline
# scalar assignment does NOT do wordsplit and glob 
echo "${energy//$'\n'/,};" >>energies_blah 
# replaces all other newlines with commas, and adds semicolon 
echo "${energy##*$'\n'}" >>final_energies_blah 
# removes everything up to and including the last newline, 
# leaving only the last number

Или вы можете выполнять всю работу с помощью awk, особенно не -древнего GNU awk с 'endfile':

# read simcount,simend and set energies,fenergies
infiles=$( printf 'sim%d/output ' $( seq $simcount $simend ) )
awk -vf1=$energies -vf2=$fenergies '/Total Energy/ {e=e","$3; f=$3} ENDFILE {print substr(e,2)";">>f1; print f>>f2; e=f=""}' $infiles

С другими awk вы можете сделать то же самое с немного более уродливым кодом (сначала! )проверка FNR==1&&NR>1конца каждого файла, кроме последнего, и (где угодно)ENDконца последнего файла.

0
28.01.2020, 03:53

Теги

Похожие вопросы