有几种方法可以解决您的问题。你选择哪一个主要取决于你想成为的awk。
在awk中声明数组:
你有什么理由不在awk中声明变量吗?
awk -F, 'BEGIN{months["JAN"]="AP01"; months["FEB"]="AP02"; months["MAR"]="AP03"; months["APR"]="AP04"; months["MAY"]="AP05"; months["JUN"]="AP06"; months["JUL"]="AP07"; months["AUG"]="AP08"; months["SEP"]="AP09"; months["OCT"]="AP10"; months["NOV"]="AP11"; months["DEC"]="AP12"}{print "a~ST_SAP_FILE~Actual~"months[substr($3,0,3)]"~RM.txt"}' ExtractOriginal.txt
(另请注意,我从 print 中删除了逗号,因为这些会添加您的问题似乎表明您不希望在结果中出现的空格)
正如@Ed Morton 所指出的,由于您的数组的性质,我们可以使用split/sprintf 简化它的创建,为您提供:
awk -F, 'BEGIN{split("JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC",t," "); for (i in t) months[t[i]]=sprintf("AP%02d",i)}{print "a~ST_SAP_FILE~Actual~"months[substr($3,0,3)]"~RM.txt"}' ExtractOriginal.txt
将变量解析成awk:
这似乎最接近您在尝试中尝试做的事情。这使数组在bash 中可用,但使用awk 处理获取您想要的文件名。由于在awk 中没有处理bash 数组的本地方法,因此您必须从前者构造后者(因为这是一个关联数组,这使这变得更加困难)。
我首先将bash 数组更改为更容易解析的字符串,然后将其作为变量传递给awk。
# Declare the array
declare -A months=( ["JAN"]="AP01" ["FEB"]="AP02" ["MAR"]="AP03" ["APR"]="AP04" ["MAY"]="AP05" ["JUN"]="AP06" ["JUL"]="AP07" ["AUG"]="AP08" ["SEP"]="AP09" ["OCT"]="AP10" ["NOV"]="AP11" ["DEC"]="AP12")
# Change the array into a string more easily parsed with awk
# Each element in this array is of the format MON=APON
mon=`for key in ${!months[@]}; do echo ${key}'='${months[${key}]}; done`
# See below explanation
awk -F, -v mon="$mon" 'BEGIN {split(mon,tmp," "); for(m in tmp){i = index(tmp[m], "="); months[substr(tmp[m], 1, i-1)] = substr(tmp[m], i+1)}} {print "a~ST_SAP_FILE~Actual~"months[substr($3,0,3)]"~RM.txt"}' ExtractOriginal.txt
下面是更易读的awk 脚本版本。请注意,-v mon="$mon" 将bash 变量mon 作为变量传递给awk,也称为mon:
BEGIN {
split(mon,tmp," "); # split the string mon into an array named tmp
for(m in tmp) { # for element in tmp
i = index(tmp[m], "="); # get the index of the '='
months[substr(tmp[m], 1, i-1)] = substr(tmp[m], i+1)
# split the elements of tmp at the '='
# and add them into an associative array called months
# the value is the part which follows the '='
}
}
{
print "a~ST_SAP_FILE~Actual~"months[substr($3,0,3)]"~RM.txt"
}
完全跳过awk:
另一种选择是根本不使用awk,这样可以消除使数组进入可用状态的负担。您的问题不清楚这是否是您的潜在解决方案,但我个人发现这个bash 版本更易于编写/阅读/理解。
#!/usr/bin/env bash
filename="ExtractOriginal.txt"
declare -A months=( ["JAN"]="AP01" ["FEB"]="AP02" ["MAR"]="AP03" ["APR"]="AP04" ["MAY"]="AP05" ["JUN"]="AP06" ["JUL"]="AP07" ["AUG"]="AP08" ["SEP"]="AP09" ["OCT"]="AP10" ["NOV"]="AP11" ["DEC"]="AP12")
while read line; do # for line in file
month_yr=`echo $line | cut -d',' -f3` # get the third column
month=${months[${month_yr:0:3}]} # get first 3 characters
echo 'a~ST_SAP_FILE~Actual~'$month'~RM.txt'
done <"$filename"