Использование Sed Ampersand Substitution с Array

1

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

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

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

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

Сара Корриэр
источник

Ответы:

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 )
choroba
источник
Я не очень знаком со сложными операторами awk, но этот код просто не работает. Единственное, что он печатает, это число, которое вы повторили в конце.
Сара С. Коррихер
@ SarahC.Corriher: Обновлено с categoryзаданием.
Чороба
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 является вредоносным).

Андраш Корн
источник
Спасибо. Хотя я хотел бы отметить для других, что кавычки вокруг выражения sed должны быть двойными кавычками, чтобы это работало.
Сара С. Корриер,
Нет. Если это двойные кавычки, оболочка попытается раскрыться ${CATEGORY[foo]}, что нарушает сценарий (или я неправильно понял, что вы пытаетесь сделать). Я специально использовал одиночные кавычки, чтобы избежать этого, чтобы sed мог видеть (и в итоге выводить) ${CATEGORY[foo]}дословно.
Андраш Корн