Если отрывок вашего кода правильно репрезентативен, похоже, что вы вводите команды Bash прямо в свой Makefile и ожидаете, что Make выполнит их с помощью Bash. Это не так. Синтаксис Makefile совершенно другой. В рецепте вы можете вводить команды Bash; каждая отдельная строка в рецепте будет выполняться в отдельной суб-оболочке. Итак, вам нужно как минимум два изменения:
должно выполняться в той же оболочке, что и цикл; в противном случае вы объявляете
в одном экземпляре Bash, затем выходите из него, а затем запускаете цикл в отдельном экземпляре, который ничего не знает о теперь потерянном объявлении
. Вот простой рефакторинг вашего Makefile с этими изменениями.
SHELL=/bin/bash # This is the standard compliant method
.PHONY: all
all:
declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 \
["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 \
["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )\
; for key in "$${!PROVS[@]}" ; do \
touch "foo_$${key}_$${PROVS[$${key}]}" ; \
done
Демонстрация: http://ideone.com/t94AOB
Соглашение @
о автоматическом запуске команды применяется ко всей командной строке. Таким образом, вы можете поместить его перед declare
выше, и в этом случае он будет удален до того, как вся командная строка будет отправлена в Bash.В другом месте он не будет удален или понят, и, очевидно, вызовет синтаксическую ошибку Bash в вызываемой оболочке.
(Одержимость правил @
в любом случае является анти-шаблоном. Выполните с помощью make -s
, если вы не хотите видеть результат; закрытие make
только усложнит отладку ваших правил.)
Я добился указанного результата за 2 шага
На первом этапе я ищу шаблон и сохраняю его в файле Output.txt
На втором шаге 2 я использовал цикл for и распечатал содержимое согласно требованию
шаг 1
egrep -i "name|count|region" l.txt | awk -F ":" '{print $NF}' | sed "s/\^M//g" >> Ouput.txt
шаг 2
for ((i=1;i<=9;i=i+3)); do sed -n ''$i',+2p' Output.txt |sed "N;s/\n/ /g" |sed "N;s/\n/ /g"; done
выход
some name 1 some_region
some name 2 some_region
some name 1 some_region
Один из возможных ответов с использованием awk:
awk '/name: /{name=substr($0,7)} /count: /{cnt=substr($0,8)} /region:/{print name" "cnt" "substr($0,9)}' input
Awk
раствор:
awk '/^(name|count|region):/{
sep = (/^region/? ORS : OFS);
gsub(/^[^:]+:[[:space:]]*|[[:space:]]*$/, "");
printf "%s%s", $0, sep
}' file.txt
Выход:
some name 1 some_region
some name 2 some_region
some name 1 some_region