2016-01-20 91 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