1

Я пытаюсь использовать символ амперсанда sed, чтобы заменить исходную строку, а затем прочитать из массива, но это не работает. Я просто получаю сообщение об ошибке: «ожидается операнд (токен ошибки« & »).

Вот соответствующая строка кода:

gawk -F '\t' '{ print $5"\t"$1"\t"$2"\t"$3"\t"$4 }' $TEMPFILE | sed "s/^[0-9]\+/${CATEGORY[&]}/g"

Первый оператор gawk создает двузначное число в начале строки. Если я заменю амперсанд в операторе sed на это число вручную, все будет работать. Буду очень признателен за помощь.

2 ответа2

3

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

Вы должны быть в состоянии сделать это непосредственно в awk :

category=(red amber green)
awk -f <( # This generates the awk code:
          echo '{';
          for (( i=0; i<${#category[@]}; i++ )) ; do
              echo category"[$i]"=\"${category[$i]}\"
          done
          echo 'print $1, category[$1]}'
      ) <( # This is the input file. 
          echo 0; echo 1 ; echo 2 )
1

Как отметила Чороба, ваша проблема в том, что ваша оболочка попытается развернуть ${CATEGORY[something]} прежде чем передать его в sed.

Если вы абсолютно хотите сделать это с помощью канала от awk до sed, это обходной путь:

awk ... | sed 's/^[0-9]\+/echo ${CATEGORY[&]}/g' | bash

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

Вы также можете попробовать

eval $(awk ... | sed 's/^[0-9]\+/echo ${CATEGORY[&]}/g')

который также будет работать без экспорта массива.

Я бы не рекомендовал ни одно из этих решений, если вы не можете быть на 100% уверены, что ваш скрипт sed не может выдавать какие-либо опасные команды (даже если ввод в awk является вредоносным).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .