Передача вывода команды в переменную в теле скрипта awk

Передача вывода команды в переменную в теле скрипта awk

Данныйinputfile

Cherries:20:100:300
Beans:12:400:500
Tomatoes:32:445:234
Potatoes:24:400:200
Kiwis:23:230:435

У меня есть скрипт awk, который называется testscript.script:

BEGIN{ FS = ":" 
print "------------------------"
}

if($3 + $4 > 500) {print $1, $2}
END{
print "------------------------" 
}

Вывод этого скрипта при вызове awk -f testscript.script inputfileвыглядит следующим образом:

------------------------
Beans 12
Tomatoes 32
Potatoes 24
Kiwis 23
------------------------

Я хочу отсортировать этот список в алфавитном порядке (по имени), а затем сохранить его в переменной, чтобы этот список можно было распечатать вконечный блокскрипта awk.

Т.е. код должен выглядеть примерно так.

BEGIN{ FS = ":" 
print "------------------------"
}

*if($3 + $4 > 500) {print $1, $2 | "sort" = variable}
END{
print "------------------------" 
print variable
}

И print variableкоманда уступит

------------
------------
Beans 12
Kiwis 23
Potatoes 24
Tomatoes 32

Используя отсортированный список элементов в качестве переменной, выведите его в блоке END после пунктирной линии.

Как лучше всего это сделать?

решение1

echo "---------------";awk -F: '$3+$4>500{print $1,$2}' inputfile |sort && echo "---------------"

с использованием awk

awk -F: '$3+$4>500{Arr[$1]=$2}END{n=asorti(Arr,SArr);for(i=1;i<=n;i++){print SArr[i],Arr[SArr[i]]}}' inputfile

решение2

При рассмотрении «лучшего» способа есть много того, что входит, я думаю о лучшем как о самом быстром маршруте, удовлетворяющем моим потребностям. Если вы пытаетесь передать переменную за пределы вашего процесса, я бы предложил передать ее на ram-диск, почти во всех дистрибутивах он есть, затем обработать ваш тест и вывести с этого ram-диска после того, как вы закончите.

В дистрибутивах на базе Debian RAM-диск расположен в /run/shm, поэтому что-то вроде этого может вам подойти.

cat inputdata.file | sed 's/:/ /g' | awk '{print $1" "$2}' | sort -k 1,1 > /run/shm/datastore.file; echo '------------------------' > datastore2.file; cat /run/shm/datastore.file>>/run/shm/datastore2.file; cat /run/shm/datastore2.file>~/destination.file

Когда способ, которым процесс хочет что-то сделать, ограничивает вас, просто управляйте форматированием с помощью логики и ramdrive. Не забудьте переместить данные после обработки, так как все в /run/shm/* будет уничтожено после перезагрузки. Надеюсь, это поможет. Буду следить, если неправильно понял, что вам нужно.

решение3

Ты можешьвставить все это в скрипт оболочкии передать вывод Awk по конвейеру до sortтого, как он будет выведен на печать.

Предположим, вам нужны строки выше и ниже отсортированного вывода (что, на мой взгляд, имеет больше смысла визуально):

#!/bin/sh
printf '%s\n' ------------------------
cat "$@" | awk -F: '($3 + $4 > 500) {print $1, $2}' | sort
printf '%s\n' ------------------------

Сохраните это в файле, назовите myscriptего исполняемым и запустите на inputfileуказанной вами платформе, вызвав:

./myscript inputfile

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

------------------------
Beans 12
Kiwis 23
Potatoes 24
Tomatoes 32
------------------------

Обратите внимание на использование "$@", чтобы этот скрипт мог обрабатывать несколько файловых аргументов, а не только один, как это может делать Awk.

Вы также можете пропустить использование catи просто сделать:

awk -F: '($3 + $4 > 500) {print $1, $2}' "$@" | sort

Однако лично мне не нравится передавать имена файлов в местах, где онимогинтерпретироваться как код. Поэтому я бы использовал catдля объединения файлов.

Связанный контент