Скрипт на shell можно вызвать из программы на awk и наоборот

Я пытаюсь найти для некоторых определенных значений (например, 1 или 4 и 2 или 3) текстовый файл, используя оператор awk в сценарии bash. Если это значение найдено в файле (в инструкции awk ), тогда я хочу вызвать функцию извне оператора awk и передать ее найденное значение в качестве аргумента.

Мои вопросы: (1) Возможно ли это? Если да, то как? (2) Если это невозможно или есть лучший способ, то как?

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

Name Col1 Col2 Col3 ———————— row1 1 4 7 row2 2 5 8 row3 3 6 9

Фактическое retrieve функции намного сложнее, чем этот упрощенный пример. Поэтому мне нужно сделать вызов этой функции, потому что я не хочу помещать это в оператор awk .

EDIT 1: Я использую GNU AWK

EDIT 2: Позволяет сказать, что у меня есть другая функция, если найдено 2 или 3. Как это будет работать тогда?

function retrieve < if [[ «$1» == «1» ]]; then echo «one beer on the wall» elif [[ «$1» == «4» ]]; then echo «four beers on the wall» fi >function retrieve2 < if [[ «$1» == «2» ]]; then echo «two beers on the wall» elif [[ «$1» == «3» ]]; then echo «three beers on the wall» fi >awk -F ‘t’ ‘ FNR < 2 FNR == NR < for (i=2; i > ‘ file.txt
Лучший ответ:

пропустить awk и сделать все в bash

Команда AWK bash скрипты по-взрослому.


tail -n +3 file.txt | while read -r ignored c1 c2 c3; do echo «$c1» echo «$c2» echo «$c3» done | while read -r value; do if [ «$value» -eq 1 -o «$value» -eq 4 ]; then retrieve «$value» elif [ «$value» -eq 2 -o «$value» -eq 3 ]; then retrieve2 «$value» fi done

  • tail пропускает первые две строки
  • первый цикл while циклически преобразует значения таблицы, игнорируя первый столбец
  • второй цикл while проверяет каждое значение и решает, какую функцию вызывать
  • оба в то время как циклы вместе примерно делают то, что сделал ваш awk-скрипт.

Вы не можете вызвать функцию оболочки непосредственно из awk-скрипта. Ваш выбор:

  1. Сохраните каждую функцию в отдельном файле сценария и вызовите этот скрипт из awk или
  2. Попросите awk передать некоторое значение обратно в оболочку, чтобы сообщить ей, какую функцию вызывать.

Хотя это не очень хорошая идея в целом, в первую очередь по соображениям производительности, есть громоздкий способ вызова функций bash из awk.

Основной подход заключается в экспорте интересующих функций, а затем вызывать их через bash -c ‘funcName arg. ‘ из awk .

Здесь доказательство концепции:

# DEFINE the function to be called from awk. # The function simply prints its arguments one by one in diagnostic fashion. retrieve() < local a i=0; for a; do echo «$$((i+=1))=[$a]»; done; ># EXPORT it, so that bash instances created by awk see the function. export -f retrieve # Simple awk program that demonstrates calling retrieve() # with an argument. awk -v q=’ ‘BEGIN < # Define some value to pass to the shell function. argToPass=»some value» # Construct the command line that will call the shell function. # Note that since a *function* is being invoked, the arguments # must be passed as part of single string passed to -c. ec=system(«bash -c » q «retrieve «» argToPass «»» q) # Print the exit code. print ec >’

Читайте также:
Программа которая показывает размеры

Обратите внимание, что каждый вызов функции оболочки будет создавать 2 дочерних процесса, так как awk function system() неизменно вызывает sh (который может быть или не быть bash на вашей системе), который в этом случае, в свою очередь, вызывает bash явно.

Linux для Начинающих — Скрипты Linux Bash, Часть-1

Пожалуйста, не принимайте этот ответ – это просто следование (и, надеюсь, помощь) от ответа Эд и ваш дальнейший вопрос.

Да, вы можете сохранить вывод awk в массиве bash, например:

array=( $(awk ‘BEGIN’) ) echo $ 1 echo $ 2 echo $ 3

Источник: techarks.ru

Скрипт на shell можно вызвать из программы на awk и наоборот

Добрый день!
можно ли вернуть значение из awk в запускающий его shell-скрипт ? z1=$(awk ‘{print $5}’ file) не подходит, потому что awk-скрипт парсит файл, выводит строки по некоторым условиям и считает количество выведенных строк.
Значение количества строк хотелось бы вернуть в sh, чтобы использовать в другом awk. Благодарю откликнувшихся.

  • z1 awk END print NR file , Andrey Mitrofanov_N0 (??), 09:54 , 11-Окт-19, (1) +1
  • Скрипт он на самом деле несколько сложнее Примерно такой bin sh awk if , d2e8k7 (ok), 11:26 , 11-Окт-19, (2)
  • gt оверквотинг удален awk ARGIND 1 count 0 nextfile output txt , Andrey Mitrofanov_N0 (??), 13:39 , 11-Окт-19, (3)
  • gt оверквотинг удален Если я правильно понял, Вы советуете обрабатывать файлы , d2e8k7 (ok), 14:03 , 11-Окт-19, (4)
  • gt оверквотинг удален Как-то не подошло такое решение для моего случаяz awk , d2e8k7 (ok), 17:42 , 16-Окт-19, ( 6 )
  • gt оверквотинг удален Если оба вызова авк так тесно связаны, логично запустить, Аноним (5), 22:13 , 16-Окт-19, ( 7 )
Сообщения [Сортировка по времени | RSS]

> z1=$(awk ‘{print $5}’ file) не подходит, потому что
> Значение количества строк хотелось бы вернуть в sh, чтобы

z1=$(awk ‘END{print NR}’ file)

>[оверквотинг удален]
> count++;
> }
> }
> END{
> print count;
> print arr;
> }’ file > output.txt
> ..
> awk ‘{}’ > хотел передать count

awk ‘ARGIND==1{count=$0;nextfile} {. }’ output.txt .

>[оверквотинг удален]
>> }
>> }
>> END{
>> print count;
>> print arr;
>> }’ file > output.txt
>> ..
>> awk ‘{}’ >> хотел передать count
> awk ‘ARGIND==1{count=$0;nextfile} {. }’ output.txt .

Если я правильно понял, Вы советуете обрабатывать файлы одним и тем же awk-скриптом
Но у меня входные файлы имеют разную структуру, поэтому и awk-скрипты для них разные.
Есть ли у awk возможность возвращать значение? ENVIRON, как я понял, не может изменить
значение переменной окружения, упомянутый в первом сообщении способ не подходит. Получается никак не вернуть? 🙁

> z1=$(awk ‘{print $5}’ file) не подходит, потому что
> awk-скрипт парсит файл, выводит строки по некоторым условиям и считает количество выведенных
> строк.
> Значение количества строк хотелось бы вернуть в sh, чтобы использовать в другом
> awk.

Вы заблуждаетесь. Отлично все подходит. Вы можете z1 подставить в текст программы awk

z1=$( awk ‘program1’ file )

awk «BEGIN { count=$z1 } /. /{ . тут что-то с использованием $count. }» file2
либо сразу в тело
awk «/. /{ . ${z1} . }» file2

Советую посмотреть какие-нибудь книжки про шелл скриптинг, sed и awk, чтобы увидеть примеры и понять, как с этим работают.
Уверен, что после пары часов чтения вы перепишете свои упражнения гораздо логичнее и короче.

>[оверквотинг удален]
> awk
> z1=$( awk ‘program1’ file )
> awk «BEGIN { count=$z1 } /. /{ . тут что-то с использованием $count.
> }» file2
> либо сразу в тело
> awk «/. /{ . ${z1} . }» file2
> Советую посмотреть какие-нибудь книжки про шелл скриптинг, sed и awk, чтобы увидеть
> примеры и понять, как с этим работают.
> Уверен, что после пары часов чтения вы перепишете свои упражнения гораздо логичнее
> и короче.

Как-то не подошло такое решение для моего случая
z=$(awk ‘{print 1; print 3; print 4 » » 5;print «End of out»} END{print 2 }’ data.txt > out.txt)
echo $z
пустой вывод

вот так я сделал:
awk ‘{print 1; print 3; print 4 » » 5;print «End of out»} END{print 2 > «cnt.txt»; print «from END»}’ data.txt > out.txt

Спасибо, что уделили внимание
count=`cat cnt.txt`
awk -v myCnt=$count ‘BEGIN{print «cnt is » myCnt}’

Т.е.
— в первом скрипте выводятся какие-то данные в файл out.txt.
— В блоке END выводим значение count в файл.
— Откуда его потом считываем и передаем в след. awk-скрипт

Спасибо, что уделили внимание

>[оверквотинг удален]
> of out»} END{print 2 > «cnt.txt»; print «from END»}’ data.txt >
> out.txt
> Спасибо, что уделили внимание
> count=`cat cnt.txt`
> awk -v myCnt=$count ‘BEGIN{print «cnt is » myCnt}’
> Т.е.
> — в первом скрипте выводятся какие-то данные в файл out.txt.
> — В блоке END выводим значение count в файл.
> — Откуда его потом считываем и передаем в след. awk-скрипт
> Спасибо, что уделили внимание

Если оба вызова авк так тесно связаны, логично запустить второй авк из первого. В том же блоке END через system().
Но все равно должен быть какой-то менее замороченный путь.

Источник: www.opennet.ru

Читайте также:
Коды управляющей программы для станков с чпу

Скрипт на shell можно вызвать из программы на awk и наоборот

Наибольшего эффекта awk достигает при использовании с другими программами. В этом подразделе обсуждаются некоторые способы взаимодействия программ awk с другими командами.

10.25.1. Функция system

Встроенная функция system (command_line) выполняет команду «command_line», которая может быть строкой, вычисляющей, например, sprintf. Функция system возвращает состояние выполненной команды.

$1 == «#include» < gsub (/[<>»]/, $2; system («cat » $2>

вызывает команду cat для печати файла, названного во втором поле каждой вводной записи, у которой первое поле #include, после разборки каждого <, >или «, которые должны присутствовать.

10.25.2. Взаимодействие с shell

Во всех приводимых примерах программа awk находилась в файле и из него осуществлялся вызов с помощью ключа -f, либо она представлялась в командной строке, заключенная в одиночные кавычки. Например:

Так как awk использует те же символы, что и shell (такие как $ и «, окружающие программу awk), одиночные кавычки обеспечат прохождение программы неизменной через shell к интерпретатору awk.

Пример. Команда addr осуществляет выборку файла addresslist для получения имени, адреса и телефона. Предположим, что addresslist содержит имена и адреса, в котором типичным входом является многострочная запись, такая как:

G. R. Emlin 600 Mountain Avenue Murray Hill, NJ 07974 201-555-1234

Записи разделяются одной пустой строкой. Вы можете выбрать список адресов с помощью командной строки, подобной:

addr Emlin
Это легко выполнить с помощью следующей программы:
awk ‘ BEGIN < RS = «» >/Emlin/ ‘ addresslist

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

Существует несколько способов сделать это. Один из способов — это создать файл, названный addr, который содержит:

Читайте также:
Документ программа и методика испытаний пример

awk ‘ BEGIN < RS = «» >/’$1’/ ‘ addresslist

В программе awk один аргумент, хотя установлено два набора кавычек, но они не являются вложенными. $1 заключено в одиночные кавычки и видимо для shell; затем будет заменено на шаблон Emlin при вызове команды addr Emlin.

Второй способ реализации addr полагается на тот факт, что shell заменяет параметры $ в двойных кавычках:

awk » BEGIN < RS = «» >/$1/ » addresslist

Кроме того, вы должны защитить кавычки, определяющие RS символами , так что shell направит их awk без интерпретации. $1 распознается как параметр и shell заменяет его на шаблон, когда команда addr вызывается с шаблоном.

Третий способ реализации addr — использовать ARGV для передачи регулярного выражения программе awk, которая читает список адресов с помощью getline:

awk ‘ BEGIN < RS = «» while ( getline < «addresslist» ) if ($0 ~ ARGV[1] print $0 >’ $*

Вся обработка выполняется в «действии» оператора BEGIN.

Обратите внимание, что регулярное выражение может быть передано addr. В частности, возможно отыскать отдельно адрес, или номер телефона, или имя.

Источник: citforum.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru