Piping a command's output to a variable in body of awk script

Команда hdfs dfs выполняет следующую команду в специальной оболочке, которая не полностью совместима с Unix, некоторые из доступных там программ похожи на программы Unix, а другие нет. Программа find является одной из них. Выражения, которые команда понимает в hdfs, следующие:

-name pattern
-iname pattern
-print
-print0Always

Таким образом, выражение, которое вы пытаетесь использовать, к сожалению, не работает в оболочке hdfs.

Источник: Документация hadoop

2
02.11.2016, 15:03
3 ответа

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

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

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

Это сохранено в файле с именем myscript , установленным в исполняемый файл и запущенным на файл ввода , указанный вами при вызове:

./myscript inputfile

Результат выглядит так:

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

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

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

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

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

0
27.01.2020, 22:10

При рассмотрении "лучшего" способа многое зависит от него, я думаю о лучшем как о самом быстром маршруте, отвечающем моим потребностям. Если вы пытаетесь передать переменную, выходящую за рамки вашего процесса, я бы предложил вывести её на 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

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

0
27.01.2020, 22:10
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
27.01.2020, 22:10

Теги

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