Можем ли мы использовать переменные оболочки в 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, используя переменные.
Ответы
Ответ 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 как массив только с одной записью, вам может потребоваться переосмыслить все, что вы пытаетесь сделать, поскольку у вас может быть совершенно неправильный подход.