Команда awk внутри цикла for

Итак, вы хотите запустить wget? Это пример извлечения файла rpm и его установки. Я также создаю файл в «/ etc / firstruns /», чтобы он не запускался каждый раз. "created" говорит: "Эй, я создаю этот файл, когда закончу ... так что, если он уже есть, мне не нужно этого делать!". Вы также можете просто указать путь в команде. Параметр пути не обязателен. Не стесняйтесь добавить и удаление оборотов.

exec { 'wget':
  path      => [ "/bin/", "/sbin/", "/usr/bin/", "/usr/sbin/" ],
  command   => "/bin/wget <URL> && rpm -ivh <RPM>",
  cwd       => '/tmp/',
  creates   => '/etc/firstruns/p1.done',
}

Могу только предположить, что меня ударили бы за неправильные действия, но это ответ: D

2
27.01.2019, 14:20
4 ответа

Вы можете выполнить то, что пытаетесь сделать, используя двойные кавычки в сценарии awk для внедрения в него переменной оболочки. Вы все еще хотите сохранить в нем один литерал $, что вы можете сделать, экранировав его обратной косой чертой:

echo $(awk -F, "{print \$$i}" <<<$var)

Это расширит $iдо 1, 2и 3в каждой из итераций, поэтому awk увидит $1, $2и $3, что заставит его расширить каждую из итераций. поля.

Другая возможность — внедрить переменную оболочки как переменную awk, используя флаг -v:

echo $(awk -F, -v i="$i" '{print $i}' <<<$var)

Это присваивает переменной awk i содержимое переменной оболочки с тем же именем. Переменные в awk не используют $, который используется для полей, поэтому $iдостаточно для ссылки на i --е поле, если i является переменной в awk..

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

Еще один вариант — использовать цикл forв самом awk. См. документацию по awk (или выполните поиск на этом сайте )для получения дополнительной информации о том, как это сделать.

5
27.01.2020, 21:52

может принимать какj(как переменную ), так и$j(как индекс поля):

for i in 1 2 3; do echo "$var" | awk -v j=$i -F, '{print $j}'; done

$iв примере «запутался» awk, какой использовать (оболочку или собственную переменную -, имеющую приоритет ), так как обе они упоминаются с префиксом $.

примечание

, стандартная для «переносимых» сценариев, не поддерживает:

(( i=1; i<=3; i++; ))и <<< $varконструкции

Также вы можете рассмотреть возможность использования команды seqв цикле forдля более точного управления генерацией числовой последовательности, если она доступна.

1
27.01.2020, 21:52

Использование awkкажется чрезмерным в данном случае, как насчет trи цикла while -:

tr, '\n' <<<"$var" | while read; do
  echo $REPLY
done

Выход:

data1
data2
data3
1
27.01.2020, 21:52
#!/bin/sh

var='data1,data2,data3'

unset data
while [ "$var" != "$data" ]; do
    data=${var%%,*}    # delete first comma and the bit after it
    var=${var#*,}      # delete bit up to first comma (and the comma)

    printf 'data = "%s"\n' "$data"
done

Здесь мы используем подстановку переменных, чтобы получить каждое последующее поле данных, разделенное запятой -, из значения переменной var. Первое присвоение dataв цикле удалит все из $varпосле первой запятой. Затем переменная varмодифицируется таким образом, что удаляется первый бит до первой запятой.

Это продолжается до "$var" = "$data", что означает, что больше ничего нельзя сделать со строкой.

Такой способ позволит нам обрабатывать разделенные запятыми -строки данных, которые содержат встроенные символы новой строки:

var='line1
line2,data2,last bit
goes here'

С указанными выше значениями в varприведенный выше скрипт выведет

data = "line1
line2"
data = "data2"
data = "last bit
goes here"

Не заботиться о встроенных новых строках; Вам очень редко приходится зацикливаться на вызовах awk.

Обратите внимание, что awkпрекрасно читает вашу строку как набор полей, -разделенных запятыми, и что он может перебирать эти:

циклы.
printf '%s\n' "$var" |
awk -F ',' '{ for (i=1; i<=NF; i++) print $i }'

С var='data1,data2,data3'будет напечатано

data1
data2
data3

Другое решение оболочки, которое использует переменную IFSдля разделения значения $varна биты, а также использует set -fдля отключения расширения имени файла:

set -f
oldIFS=$IFS; IFS=','

set -- $var

IFS=$oldIFS; unset oldIFS
set +f

for data do
    printf 'data = "%s"\n' "$data"
done
0
27.01.2020, 21:52

Теги

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