Reputation: 259
So i am trying to change all dates in a text file from
1-1-1111(Month,Day,Year)to
January 1, 1111(Month,Day,Year)sed 's/[0-9]\{1\}-[0-9]\{1\}-[0-9]\{4\}/date -d"+%B +%d, +%Y"/g'
I'm not sure how to format from "date" on. If I add other single quotes it won't function correctly. It is not functioning correctly as is but I know i want to use
date -d"+%B +%d, +%Y"
on the second half of
sed's///g'
Upvotes: 1
Views: 1574
Reputation: 241828
You can generate the sed script in bash to avoid calls to external tools:
#!/bin/bash
idx=12
for month in Dec Nov Oct Sep Aug Jul Jun May Apr Mar Feb Jan ; do
echo "s/$idx-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/$month \1, \2/g"
(( idx-- ))
done
Note that I use the months in reverse order to prevent 12
to be translated to 1Feb
.
Saved as script.sh
, it generates the following sed script:
s/12-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Dec \1, \2/g
s/11-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Nov \1, \2/g
s/10-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Oct \1, \2/g
s/9-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Sep \1, \2/g
s/8-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Aug \1, \2/g
s/7-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Jul \1, \2/g
s/6-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Jun \1, \2/g
s/5-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/May \1, \2/g
s/4-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Apr \1, \2/g
s/3-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Mar \1, \2/g
s/2-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Feb \1, \2/g
s/1-\([0-9]\{1,2\}\)-\([0-9]\{4\}\)/Jan \1, \2/g
Then, run
script.sh | sed -f- file
Upvotes: 1
Reputation: 241828
Perl to the rescue (using Time::Piece):
perl -MTime::Piece -pe 'BEGIN { @months = ( undef, Time::Piece::mon_list() ) }
s/([0-9]{1,2})-([0-9]{1,2})-([0-9]{4})/$months[$1] $2, $3/g' < input > output
Upvotes: 0
Reputation: 4205
In your example, you use simple quote to protect the sed expression, that's why you CANNOT use other simple quote inside (there is no escape in this case).
If your sed is GNU sed. you can use 'e' to pass matched group to external command/tools within sed command as explained here.
But it means you call an external command for each match. So this solution can be slow if your text contains a lot of dates.
If you have only one date by line, I suggest the following script :
sed -r 's#([0-9]{1,2})-([0-9]{1,2})-([0-9]{4})#date -d"\1/\2/\3" +"%B %d, %Y"#e'
Upvotes: 2