Как вы перебираете последовательно пронумерованные псевдонимы?

С GNU awk:

awk -v FIELDWIDTHS='4 7 3 4 4' '
    NR>2 {
        if ($4 <= 11)
            $4 += 10
        else if ($4 >= 12 && $4 <= 15) { 
            $3 = "B"
            $4 -= 11
        }
        else if ($4 >= 16) { 
            $3 = "C"
            $4 -= 15
        }
        $3 = sprintf("%3s", $3)
        $4 = sprintf("%4d", $4)
    }
    1' datafile3248.dat

Вывод:

HEAD
DESCRIPTION
NAME       1   A   18    X
NAME       2   A   18    X
NAME       3   A   19   XX
NAME       4   A   19   XX
NAME       5   A   19    Y
NAME       6   A   20    Y
NAME       7   A   21   XY
NAME       8   A   21   XZ
NAME       9   B    1    Z
NAME      10   B    2    Z
NAME      11   B    2    Z
NAME      12   B    2   YZ
NAME      13   B    3   ZZ
NAME      14   B    4    X
NAME      15   C    1   XX
NAME      16   C    1    X
NAME      17   C    1    Y
NAME      18   C    2   YY
0
04.06.2017, 06:12
4 ответа

Из-за порядка оценки вещей, echo$i будет оцениваться как строка echo1 (для i=1) после расширение псевдонима.

Чтобы иметь возможность использовать строку в качестве псевдонима, вам необходимо переоценить результирующую строку:

for i in 1 2 3; do
    eval "echo$i"
done

Если echo1, echo2 и echo3 были функциями оболочки, тогда eval не понадобились (проверено в Bash 4.4).

Ваши попытки с bash -c не сработают, поскольку псевдонимы являются локальными для текущего сеанса оболочки.

Ваша исходная вещь

echo{1..3}

приведет к

echo1 echo2 echo3

Даже если echo1 будет расширен до echo 1, результатом будет вывод строки

1 echo2 echo3

Personally , в зависимости от того, что вы хотели, чтобы псевдонимы фактически делали, я бы реализовал функцию:

dothing () {
    printf '%s\n' "$@"
}

... и затем вызвал это с помощью

dothing {1..3}

для получения

1
2
3

Конечно, это было бы достигнуто с помощью printf '%s\n' {1..3} напрямую...

3
28.01.2020, 02:25

Вы всегда можете сделать:

eval echo{1..3}\;

Это означает, что оболочка оценивает расширение этого как код оболочки, то есть оценивает:

echo1; echo2; echo3;

Некоторые другие варианты:

eval echo{1..3}$'\n' # separate with newline instead of ;. Can make a
                     # difference for things like alias echo1='echo x|'
                     # alias echo2='tr x y'

eval echo{1..3}'&&' : # only run the next one if the previous one succeeded
0
28.01.2020, 02:25

Почему бы не сделать еще одну функцию, которая будет выполнять псевдонимы?

function execute_all_aliases{
  alias1
  alias2
  alias3
}
0
28.01.2020, 02:25

Благодаря @Kusalananda я нашел следующее решение:

printf '%s\n' {1..3} | xargs -I {} bash -ic "echo{}"

Это позволит выполнить n псевдонимов, названных последовательно с другими командными частями

0
28.01.2020, 02:25

Теги

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