我有一个数据集,有一个长长的日期列表,格式是'DD-MM-YYYY‘。对我来说,唯一重要的部分是月份,我想重新格式化这些字符串,使其具有月份的字符串表示形式,例如将'23-01-1994‘替换为’一月‘。
在sed或其他实用程序中,是否有流线型工具将这些字符串替换为它们的同月名称?
发布于 2015-01-08 23:32:14
如果您不介意使用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-ing填充split数组,这是一个空格分隔的字符串。
然后,对于每一行输入,我们以%s-%s-%s格式输出一个字符串,其中%s将被我们提供的变量填充。我们必须这样做,因为我们在-上拆分了输入字符串,所以我们需要重新组装它。第一个和第三个字段保持不变,但第二个字段将转换为一个数字,并用作选择月份文本的索引。例如,如果$2包含07,我们将将其转换为一个数字7,并使用与Jul相对应的month[7]。
发布于 2015-01-08 23:20:27
这将是一个很长很长的命令:
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/' \
...与sed不同,ou可以在Unix/Linux中使用date命令。不过要小心点。date命令在Mac和GNU平台(如Linux )等BSD平台上的工作方式完全不同。
在Mac上:
$ date -j -f '%d-%m-%Y' '23-01-1994' +"%B"
January发布于 2015-01-08 23:48:36
由于您指定了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]格式更可靠。
https://stackoverflow.com/questions/27850906
复制相似问题