web-dev-qa-db-fra.com

Extraire la sous-chaîne en utilisant regex en plain bash

J'essaie d'extraire le temps d'une chaîne en utilisant bash, et j'ai du mal à le comprendre.

Ma chaîne est comme ça:

US/Central - 10:26 PM (CST)

Et je veux extraire le 10:26 partie.

Quelqu'un sait comment faire cela uniquement avec bash - sans utiliser sed, awk, etc.?

Par exemple, dans PHP je voudrais utiliser - pas la meilleure façon, mais cela fonctionne - quelque chose comme:

preg_match( ""(\d{2}\:\d{2}) PM \(CST\)"", "US/Central - 10:26 PM (CST)", $matches );

Merci pour toute aide, même si la réponse utilise sed ou awk

81
andrux

Utilisation de pure bash :

$ cat file.txt
US/Central - 10:26 PM (CST)
$ while read a b time x; do [[ $b == - ]] && echo $time; done < file.txt

une autre solution avec bash regex:

$ [[ "US/Central - 10:26 PM (CST)" =~ -[[:space:]]*([0-9]{2}:[0-9]{2}) ]] &&
    echo ${BASH_REMATCH[1]}

une autre solution utilisant grep et une expression rationnelle avancée:

$ echo "US/Central - 10:26 PM (CST)" | grep -oP "\-\s+\K\d{2}:\d{2}"

une autre solution utilisant sed:

$ echo "US/Central - 10:26 PM (CST)" |
    sed 's/.*\- *\([0-9]\{2\}:[0-9]\{2\}\).*/\1/'

une autre solution utilisant Perl:

$ echo "US/Central - 10:26 PM (CST)" |
    Perl -lne 'print $& if /\-\s+\K\d{2}:\d{2}/'

et le dernier utilisant awk:

$ echo "US/Central - 10:26 PM (CST)" |
    awk '{for (i=0; i<=NF; i++){if ($i == "-"){print $(i+1);exit}}}'
173
Gilles Quenot
    echo "US/Central - 10:26 PM (CST)" | sed -n "s/^.*-\s*\(\S*\).*$/\1/p"

-n      suppress printing
s       substitute
^.*     anything at the beginning
-       up until the dash
\s*     any space characters (any whitespace character)
\(      start capture group
\S*     any non-space characters
\)      end capture group
.*$     anything at the end
\1      substitute 1st capture group for everything on line
p       print it
69
jgshawkey

Technique chop-chop Quick-n dirty, sans regex, à faible robustesse

string="US/Central - 10:26 PM (CST)"
etime="${string% [AP]M*}"
etime="${etime#* - }"
24
doubleDown