150 votes

Extraire une sous-chaîne à l'aide d'un regexp en bash simple

J'essaie d'extraire l'heure d'une chaîne de caractères en utilisant bash, et j'ai du mal à trouver la solution.

Ma chaîne est comme ça :

US/Central - 10:26 PM (CST)

Et je veux extraire le 10:26 partie.

Quelqu'un connaît-il un moyen de faire cela uniquement avec bash - sans utiliser sed, awk, etc ?

Par exemple, en PHP, j'utiliserais - ce n'est pas la meilleure façon de faire, mais ça marche - 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.

298voto

sputnick Points 31663

En utilisant des 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 look-around regex avancé :

$ 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 en utilisant awk :

$ echo "US/Central - 10:26 PM (CST)" |
    awk '{for (i=0; i<=NF; i++){if ($i == "-"){print $(i+1);exit}}}'

162voto

jgshawkey Points 841
    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

39voto

doubleDown Points 3245

Technique de découpage rapide et sale, sans regex, à faible robustesse.

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

6voto

LeChatDeNansen Points 21

Si votre chaîne est

foo="US/Central - 10:26 PM (CST)"

puis

echo "${foo}" | cut -d ' ' -f3

fera l'affaire.

-2voto

Jimbro Points 1

Foo="US/Central - 10:26 PM (CST)"

echo ${foo} | date +%H:%M

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X