Подтвердить что ты не робот

Можем ли мы использовать переменные оболочки в awk?

Можно ли использовать переменные оболочки в AWK как $VAR вместо $1, $2? Например:

UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW)

NUSR=`echo ${UL[*]}|awk -F, '{print NF}'`
echo $NUSR
echo ${UL[*]}|awk -F, '{print $NUSR}'

На самом деле это Oracle DBA, мы получаем много запросов на импорт. Я пытаюсь автоматизировать его с помощью script. script обнаружит пользователей в дампе и предложит пользователям, для которых необходимо загрузить дамп.

Предположим, что дампы имеют двух пользователей AKHIL, SWATHI (могут быть пользователи в дампе, и я хочу импортировать больше пользователей). Я хочу импортировать дампы для новых пользователей AKHIL_NEW и SWATHI_NEW. Таким образом, ввод, который нужно прочитать, кажется, как AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW.

Во-первых, мне нужно найти количество пользователей, которые будут созданы, тогда мне нужно получить новых пользователей, т.е. AKHIL_NEW,SWATHI_NEW, из введенного нами ввода. Чтобы я мог подключиться к базе данных и создавать новых пользователей, а затем импортировать. Я не копирую весь код: я просто скопировал код, откуда он принимает входных пользователей.

UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW) ## it can be many users like     USER1:USER1_NEW,USER2_USER2_NEW,USER3:USER_NEW..

NUSR=`echo ${UL[*]}|awk -F, '{print NF}'` #finding  number of fields or users
y=1
while [ $y -le $NUSR ] ; do
    USER=`echo ${UL[*]}|awk -F, -v NUSR=$y  '{print $NUSR}' |awk -F: '{print $2}'` #getting     Users to created AKHIL_NEW and SWATHI_NEW and passing to SQLPLUS
    if [[ $USER = SCPO* ]]; then
        TBS=SCPODATA
    else
        if [[ $USER = WWF* ]]; then
            TBS=WWFDATA
        else
            if [[ $USER = STSC* ]]; then
                TBS=SCPODATA
            else
                if [[ $USER = CSM* ]]; then
                    TBS=CSMDATA
                else
                    if [[ $USER = TMM* ]]; then
                        TBS=TMDATA
                    else
                        if [[ $USER = IGP* ]]; then
                        TBS=IGPDATA
                        fi
                    fi
                fi
             fi
        fi
    fi

    sqlplus -s '/ as sysdba'  <<EOF   # CREATING the USERS in the database 
    CREATE USER $USER IDENTIFIED BY $USER  DEFAULT TABLESPACE $TBS TEMPORARY TABLESPACE TEMP QUOTA 0K on SYSTEM QUOTA UNLIMITED ON $TBS;

    GRANT
    CONNECT,
       CREATE TABLE,
       CREATE VIEW,
       CREATE SYNONYM,
       CREATE SEQUENCE,
       CREATE DATABASE LINK,
       RESOURCE,
       SELECT_CATALOG_ROLE
    to $USER;
    EOF 
    y=`expr $y + 1`
done

impdp sysem/manager DIRECTORY=DATA_PUMP DUMPFILE=imp.dp logfile=impdp.log SCHEMAS=AKHIL,SWATHI REMPA_SCHEMA=${UL[*]} 

В последней команде impdp мне нужно получить исходных пользователей в дампах i.e AKHIL, SWATHI, используя переменные.

4b9b3361

Ответ 1

Ваш код не имеет смысла, но на вопрос легко ответить: да, вы можете использовать переменные оболочки внутри awk. Есть несколько способов сделать это, но моим фаворитом является определение переменной с флагом -v:

$ echo | awk -v my_var=4 '{print "My var is " my_var}'
My var is 4

Просто передайте переменную окружения в качестве параметра в флаг -v. Например, если у вас есть эта переменная:

$ VAR=3
$ echo $VAR
3

Используйте его следующим образом:

$ echo | awk -v env_var="$VAR" '{print "The value of VAR is " env_var}'
The value of VAR is 3

Конечно, вы можете указать одно и то же имя, но $ не понадобится:

$ echo | awk -v VAR="$VAR" '{print "The value of VAR is " VAR}'
The value of VAR is 3

Заметка о $ в awk: в отличие от bash, Perl, PHP и т.д. это не часть имени переменной, а оператор.

Ответ 2

Есть два способа передать переменные в awk: один путь определяет переменную в аргументе командной строки:

$ echo ${UL[*]}|awk -F, -v NUSR=$NUSR '{print $NUSR}'
SWATHI:SWATHI_NEW

Другим способом является преобразование переменной оболочки в переменную среды с помощью export и чтение переменной окружения из массива ENVIRON:

$ export NUSR
$ echo ${UL[*]}|awk -F, '{print $ENVIRON["NUSR"]}'
SWATHI:SWATHI_NEW

Обновление 2016: OP имеет данные, разделенные запятыми, и хочет извлечь элемент с учетом его индекса. Индекс находится в переменной оболочки NUSR. Значение NUSR передается в awk, а оператор awk доллар извлекает элемент.

Обратите внимание, что было бы проще объявить UL как массив из более чем одного элемента и выполнить извлечение в bash и полностью вывести awk из уравнения. Это, однако, использует индексирование на основе 0.

UL=(AKHIL:AKHIL_NEW SWATHI:SWATHI_NEW)
NUSR=1
echo ${UL[NUSR]} # prints SWATHI:SWATHI_NEW

Ответ 3

Awk и Gawk предоставляют ассоциативный массив ENVIRON, который содержит все экспортированные переменные среды. Таким образом, в вашем awk script вы можете использовать ENVIRON [ "VarName" ], чтобы получить значение VarName, при условии, что VarName был экспортирован до запуска awk.

Примечание. ENVIRON - это предопределенная переменная awk, а не переменная среды оболочки.

Поскольку у меня недостаточно репутации, чтобы прокомментировать другие ответы, я должен включить их здесь!

Более ранний ответ с указанием $ENVIRON неверен - этот синтаксис будет расширяться оболочкой и, вероятно, приведет к расширению до нуля.

Более ранние комментарии о том, что C не может получить доступ к переменной среды, неверны. В отличие от сказанного выше, C (и С++) могут обращаться к переменным среды, используя функцию getenv ( "VarName" ). Многие другие языки обеспечивают аналогичный доступ (например, Java: System.getenv(), Python: os.environ, Haskell System.Environment,...). Обратите внимание, что во всех случаях доступ к переменным окружения доступен только для чтения, вы не можете изменить переменную среды в программе и вернуть это значение в вызывающий script.

Ответ 4

Не уверен, что я понимаю ваш вопрос.

Но скажем, мы получили переменную number=3, и мы хотим использовать ее istead из $3, в awk мы можем сделать это со следующим кодом

results="100 Mbits/sec 110 Mbits/sec 90 Mbits/sec"
number=3    
speed=$(echo $results | awk '{print '"\$${number}"'}')

чтобы переменная скорости получала значение 110.

Надеюсь, что это поможет.

Ответ 5

Есть и другой способ, но это может вызвать огромную путаницу:

$ VarName="howdy" ; echo | awk '{print "Just saying '$VarName'"}'
Just saying howdy
$

Итак, вы временно выходите из среды одиночной кавычки (которая обычно препятствует интерпретации интерпретатора "$" ) интерпретацией переменной и последующим возвратом в нее. Это имеет силу быть относительно коротким.

Ответ 6

Нет. Вы можете передать значение переменной оболочки awk script так же, как вы можете передать значение переменной оболочки в программу C, но вы не можете получить доступ к переменной оболочки в awk script больше, чем вы могли бы получить доступ к shell в программе C. Подобно C, awk не является оболочкой. См. Вопрос 24 в справке comp.unix.shell на cfajohnson.com/shell/cus-faq-2.html#Q24.

Один из способов написания кода:

UL="AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW"
NUSR=$(awk -F, -v ul="$UL" 'BEGIN{print gsub(FS,""); exit}')
echo "$NUSR"
echo "$UL" | awk -F, -v nusr="$NUSR" '{print $nusr}' # could have just done print $NF

но с вашей исходной отправной точки:

UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW)

объявлял UL как массив только с одной записью, вам может потребоваться переосмыслить все, что вы пытаетесь сделать, поскольку у вас может быть совершенно неправильный подход.