2016-01-20 66 views
1

我使用sed重新格式化输入字符串,其中一部分我想用其他字符串替换。使用sed替换关联bash数组中的匹配值

输入字符串是在量的格式的日期:

%Y-%m-%dT%H:%M:%S.%N%:z 
Example: 
2016-01-20T08:15:32.398242-05:00 

我的目标是在该示例中,以取代个月01以上,具有一个字符串表示如Jan

我定义以下数组来使用:

declare -A MONTHS=([01]="Jan" [02]="Feb" [03]="Mar" [04]="Apr" [05]="May" [06]="Jun" [07]="Jul" [08]="Aug" [09]="Sep" [10]="Oct" [11]="Nov" [12]="Dec") 

我似乎无法得到sed使用匹配的组的值作为索引到MONTHS阵列。

我已经试过什么:

# straightforward sed approach 
sed 's/^[0-9]\{4\}-\([0-9]\{2\}\)-.*/${MONTHS[\1]}/g' 
# result: ${MONTHS[01]} 

# break out of the single quotes 
sed 's/^[0-9]\{4\}-\([0-9]\{2\}\)-.*/'"${MONTHS[\1]}"'/g' 
# result: 

# use double quotes 
sed "s/^[0-9]\{4\}-\([0-9]\{2\}\)-.*/${MONTHS[\1]}/g" 
# result: 

# use double quotes *and* a hardcoded example 
sed "s/^[0-9]\{4\}-\([0-9]\{2\}\)-.*/${MONTHS[\1]}, ${MONTHS[01]}/g" 
# result: , Jan 

是否有可能使用来自sed匹配的组值作为替换数组索引?

注:我故意避开date功能,因为这个应用程序可以超越实际的日期;但是,我绝对愿意采用替代方法,如awk

回答

2

我建议这个awk作为替代:

s='2016-01-20T08:15:32.398242-05:00' 

awk -v ms='Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec' 'BEGIN{ 
    split(ms, mths, ":"); FS=OFS="-"} {$2=mths[$2+0]} 1' <<< "$s" 

输出:

2016-Jan-20T08:15:32.398242-05:00 
+1

哦,太棒了,这很好用!我非常喜欢它可以让我内嵌替换值,而其他一切都很容易根据我的需要进行修改。谢谢=] – newfurniturey

1

首先,您可以将您的关联数组转换为包含月份名称的字符串,以

monstr=$(for k in "${!MONTHS[@]}"; do echo $k; done | sort | while read mon; do echo ${MONTHS[$mon]}; done) 

然后,用awk做繁重

awk -F- -v monstr="$monstr" 'BEGIN { split(monstr, mon, " "); } { printf("%s-%s-", $1, mon[$2+0]); for (i=3; i < NF; i++) { printf("%s-", $i); } printf("%s\n", $NF);}' 

也就是说,存储字符串包含您在开始时拆分的变量中的月份,然后替换第二个字段并全部打印。

+0

该作品完美,谢谢!多重的'printf()'语句让我们开始修改起来有点困惑,但我现在已经掌握了它,它的工作原理就是我需要的=] – newfurniturey

0

首先生成与阵列sed脚本,然后执行它。

声明:不确定是否在下面的代码中正确使用了bash数组。也不确定引号和转义。

for k in $(seq -w 1 12) ; do 
    echo 's/^[0-9]\{4\}-'"$k-.*/${MONTHS[$k]}/;" 
done | sed -f - your_file 

或者只是使用bash

IFS=- read year mon rest <<<"$string" 
string="$year ${MONTHS[$mon]} $rest" 
0

如果一定要sed的......下面是使用命令 “强力” 的答案:

#! /bin/sed -f 
s/-01-/-Jan-/; tx 
s/-02-/-Feb-/; tx 
s/-03-/-Mar-/; tx 
s/-04-/-Apr-/; tx 
s/-05-/-May-/; tx 
s/-06-/-Jun-/; tx 
s/-07-/-Jul-/; tx 
s/-08-/-Aug-/; tx 
s/-09-/-Sep-/; tx 
s/-10-/-Oct-/; tx 
s/-11-/-Nov-/; tx 
s/-12-/-Dec-/; tx 
:x