with sed, one possibility is:
echo "May 5 2014" | sed 's/.* \([0-9]*\) .*/\1/'
another one
echo "May 5 2014" | sed 's/[^ ]* //;s/ [^ ]*//'
another
echo "May 5 2014" | sed 's/\(.*\) \(.*\) \(.*\)/\2/'
with grep
echo "May 5 2014" | grep -oP '\b\d{1,2}\b'
or perl
echo "May 5 2014" | perl -lanE 'say $F[1]'
as curiosity
echo "May 5 2014" | xargs -n1 | head -2 | tail -1
echo "May 5 2014" | xargs -n1 | sed -n 2p
echo "May 5 2014" | xargs -n1 | egrep '^[0-9]{1,2}$'
and finally, pure bash solution, without starting any external commands
aaa="May 5 2014"
[[ $aaa =~ (.*)[[:space:]](.*)[[:space:]](.*) ]] && echo ${BASH_REMATCH[2]}
or
aaa="May 5 2014"
re="(.*) (.*) (.*)"
[[ $aaa =~ $re ]] && echo ${BASH_REMATCH[2]}
EDIT
Because Keith Reynolds asking for some benchmarks, i tested the following script. Using time
is not the perfect benchmarking tool, but gives some insight.
- each test outputs N-times the result (what is counted by wc)
- NOTE, the external commands are executed only 10_000 times while the pure bash solutions 100_000 times
Here is the script:
xbench_with_read() {
let i=$1; while ((i--)); do
read _ day _ <<< 'May 5 2014'
echo $day
done
}
xbench_regex_3x_assign() {
let i=$1; while ((i--)); do
aaa="May 5 2014"
re="(.*) (.*) (.*)"
[[ $aaa =~ $re ]] && month="${BASH_REMATCH[1]}" && day="${BASH_REMATCH[2]}" && year="${BASH_REMATCH[3]}" && echo "$day"
done
}
xbench_regex_1x_assign() {
let i=$1; while ((i--)); do
aaa="May 5 2014"
re="(.*) (.*) (.*)"
[[ $aaa =~ $re ]] && day=${BASH_REMATCH[2]} && echo "$day"
done
}
xbench_var_expansion() {
let i=$1; while ((i--)); do
s="May 5 2014"
t="${s#* }"
echo "${t% *}"
done
}
xbench_ext_cut() {
let i=$1; while ((i--)); do
echo "May 5 2014" | cut -d' ' -f2
done
}
xbench_ext_grep() {
let i=$1; while ((i--)); do
echo "May 5 2014" | grep -oP '\b\d{1,2}\b'
done
}
xbench_ext_sed() {
let i=$1; while ((i--)); do
echo "May 5 2014" | sed 's/\(.*\) \(.*\) \(.*\)/\2/'
done
}
xbench_ext_xargs() {
let i=$1; while ((i--)); do
echo "May 5 2014" | xargs -n1 | sed -n 2p
done
}
title() {
echo '~ -'$___{1..20} '~' >&2
echo "Timing $1 $2 times" >&2
}
for script in $(compgen -A function | grep xbench)
do
cnt=100000
#external programs run 10x less times
[[ $script =~ _ext_ ]] && cnt=$(( $cnt / 10 ))
title $script $cnt
time $script $cnt | wc -l
done
and here are the raw results:
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_ext_cut 10000 times
10000
real 0m37.752s
user 0m14.587s
sys 0m25.723s
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_ext_grep 10000 times
10000
real 1m35.570s
user 0m21.778s
sys 0m34.524s
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_ext_sed 10000 times
10000
real 0m41.628s
user 0m15.310s
sys 0m26.422s
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_ext_xargs 10000 times
10000
real 1m42.235s
user 0m46.601s
sys 1m11.238s
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_regex_1x_assign 100000 times
100000
real 0m11.215s
user 0m8.784s
sys 0m0.907s
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_regex_3x_assign 100000 times
100000
real 0m14.669s
user 0m12.419s
sys 0m1.027s
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_var_expansion 100000 times
100000
real 0m5.148s
user 0m4.658s
sys 0m0.788s
~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~ - ~
Timing xbench_with_read 100000 times
100000
real 0m27.700s
user 0m6.279s
sys 0m19.724s
So sorted by real execution time
pure bash solutions 100_000 times
- xbench_var_expansion - real 0m5.148s - 5.2 sec
- xbench_regex_1x_assign - real 0m11.215s - 11.2 sec
- xbench_regex_3x_assign - real 0m14.669s - 14.7 sec
- xbench_with_read - real 0m27.700s - 27.7 sec
No surprises here - the variable expansion is simply the fastest solution.
external programs only 10_000 times
- xbench_ext_cut - real 0m37.752s - 37.8 sec
- xbench_ext_sed - real 0m41.628s - 41.6 sec
- xbench_ext_grep - real 1m35.570s - 95.6 sec
- xbench_ext_xargs - real 1m42.235s - 102.2 sec
Two surprises here (at least for me):
- the
grep
solution is 2x slover as sed
- the
xargs
(curiosity solution) only slightly slower as grep
Enviromnent:
$ uname -a
Darwin marvin.local 13.1.0 Darwin Kernel Version 13.1.0: Thu Jan 16 19:40:37 PST 2014; root:xnu-2422.90.20~2/RELEASE_X86_64 x86_64
$ LC_ALL=C bash --version
GNU bash, version 4.2.45(2)-release (i386-apple-darwin13.0.0)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>