用于替换日期字符串的Sed命令' DD-03-YYYY'使用该月的字符串,例如'三月'

时间:2015-01-08 22:44:52

标签: regex string bash date sed

我的数据集中包含一长串日期,格式为'DD-MM-YYYY'。对我来说唯一重要的部分是月份,我想重新格式化这些字符串以获得月份的字符串表示,例如将'23 -01-1994'替换为'January'。

在sed或其他一些实用程序中是否有一个简化的原因,用它们的月份等价物替换这些字符串?

3 个答案:

答案 0 :(得分:3)

如果你对awk而不是sed没问题,那么效果很好:

awk -F'-' 'BEGIN { split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", month, " "); } { printf "%s-%s-%s\n", $1, month[int($2)], $3; }'

<强>解释

首先,我们将awk的字段分隔符更改为-字符。这使得位置变量现在包含日,月和年 BEGIN块在处理第一行之前运行。为简单起见,我们用split填充month数组 - 用空格分隔的字符串。
然后,对于每一行输入,我们输出格式为%s-%s-%s的字符串,其中%s将填入我们提供的变量。我们必须这样做是因为我们将输入字符串拆分为-,因此我们需要重新组合它。第一个和第三个字段保持原样,但第二个字段将转换为数字并用作索引以选择月份文本。例如,如果$2包含07,我们会将其转换为数字7并使用与month[7]对应的Jul

答案 1 :(得分:0)

这将是一个很长很长的sed命令:

 sed -E -e 's/\d\d-01-\d\d\d\d/January/' \
    -e 's/\d\d-02-\d\d\d\d/February/' \
    -e 's/\d\d-03-\d\d\d\d/March/' \
    -e 's/\d\d-04-\d\d\d\d/April/' \
    ...

您可以在Unix / Linux中使用sed命令而不是date。但要小心。 date命令在BSD平台上的工作方式完全不同,如Mac和GNU平台,如Linux。

在Mac上:

$ date -j -f '%d-%m-%Y' '23-01-1994' +"%B"            
January

答案 2 :(得分:0)

由于您指定了sed,因此可以使用以下方法构建相应的sed命令。首先,让我们从定义bash数组开始:

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)

其次,让我们使用所有需要的cmd命令创建一个shell变量sed

printf -v cmd 's/[[:digit:]]{2}-%s-[[:digit:]]{4}/%s/g; ' "${months[@]}"

最后,我们使用sed:

sed -re "$cmd" input_file

举个例子:

$ echo '01-02-2003 01-12-2004' | sed -re "$cmd"
Feb Dec

更多详情

使用sed,需要12个替换命令,每个月一个。 printf命令从months变量创建全部12。

$ printf -v cmd 's/[[:digit:]]{2}-%s-[[:digit:]]{4}/%s/g; ' "${months[@]}"
$ echo "$cmd"
s/[[:digit:]]{2}-01-[[:digit:]]{4}/Jan/g; s/[[:digit:]]{2}-02-[[:digit:]]{4}/Feb/g; s/[[:digit:]]{2}-03-[[:digit:]]{4}/Mar/g; s/[[:digit:]]{2}-04-[[:digit:]]{4}/Apr/g; s/[[:digit:]]{2}-05-[[:digit:]]{4}/May/g; s/[[:digit:]]{2}-06-[[:digit:]]{4}/Jun/g; s/[[:digit:]]{2}-07-[[:digit:]]{4}/Jul/g; s/[[:digit:]]{2}-08-[[:digit:]]{4}/Aug/g; s/[[:digit:]]{2}-09-[[:digit:]]{4}/Sep/g; s/[[:digit:]]{2}-10-[[:digit:]]{4}/Oct/g; s/[[:digit:]]{2}-11-[[:digit:]]{4}/Nov/g; s/[[:digit:]]{2}-12-[[:digit:]]{4}/Dec/g; 

以上是漫长的。让我们随机从列表中取一个替代命令:

s/[[:digit:]]{2}-09-[[:digit:]]{4}/Sep/g;

这会查找任意两位数,然后是-09-,后跟任意四位数字,并将其替换为字符串Sep。由于最终的g,这是在线上找到的每个这样的日期完成的。

请注意[[:digit:]]的使用。这将匹配我们所处的任何区域中的任何数字。在具有unicode字体的现代世界中,这比旧的[0-9]形式更可靠。