Comment supprimer le premier deux-points ':' d'un horodatage?

10

Je suis nouveau en programmation !!

Quelqu'un peut-il aider à supprimer :la première position dans un horodatage::29.06.2019 23:03:17

Actuellement, j'essaie de le faire en utilisant les commandes awk / cut comme indiqué ci-dessous:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2)"
echo "$TDS"


29.06.2019 23

Et la sortie n'est pas ce que je voulais! Je veux l'imprimer comme 29.06.2019 23:03:17.

Manoj Kumar
la source

Réponses:

14

Pour couper le premier caractère, vous pouvez également utiliser cut -c:

$ echo ":29.06.2019 23:03:17" | cut -c 2-
29.06.2019 23:03:17
pLumo
la source
11

Utilisation

cut -d: -f2-

au lieu de

cut -d: -f2

pour obtenir quoi que ce soit du deuxième champ à la fin de la ligne:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2-)"
echo "$TDS"
Florian Diesch
la source
8

awkest un outil génial, et vous pouvez résoudre des tâches très complexes avec lui. Mais pour votre question, je préfère m'en tenir aux capacités de base de bash.

Pour cette suppression de sous-station facile, je ferais ce qui suit:

zehe="Logfile started :29.06.2019 23:03:17"
echo "${zehe#*:}"

cela imprimera:

29.06.2019 23:03:17

Quand j'étais à votre poste et que j'ai commencé à apprendre la programmation et le bash, j'ai appris beaucoup de ce manuel:

ABS - Guide avancé de Bash-Scripting

Vous trouverez ici d' autres exemples et des informations intéressantes sur votre problème , recherchez «Suppression de sous-chaîne».

Hannes Morgenstern
la source
3
+1 ceci! Étant donné que la question est étiquetée "bash", il convient d'envisager de préférer les grandes capacités de bash (bien que souvent assez obscures) de manipulation de chaînes qui sont beaucoup plus rapides que le chargement d'outils externes.
rexkogitans
2
@rexkogitans puisque nous appelons déjà grep ou awk pour analyser un fichier, bash ne sera pas plus rapide. En fait, chaque fois que vous devez analyser un fichier bash sera lent. Tous les obus sont lents et bash est plus lent que la plupart. Cela dit, les capacités de manipulation de chaînes du shell sont en effet souvent la meilleure approche, mais seulement si vous avez déjà l'entrée en tant que variable.
terdon
8

Voici une sedsolution:

$ echo ':29.06.2019 23:03:17' | sed 's/^://'
29.06.2019 23:03:17

La commande sed 's/^://'remplace sle caractère deux-points :du début ^de chaque ligne par la chaîne vide //.

Voici une awksolution délicate , où nous changeons le séparateur de champ en ^:, décrit ci-dessus, et sortons le deuxième champ (de chaque ligne):

$ echo ':29.06.2019 23:03:17' | awk -F'^:' '{print $2}'
29.06.2019 23:03:17

La tâche pourrait également être accomplie avec grep( explication ), cela pourrait probablement être la solution la plus rapide pour une grande quantité de données:

$ echo 'Logfile started :29.06.2019 23:03:17' | grep -Po '^Logfile started :\K.*'
29.06.2019 23:03:17

Ou traitez le fichier directement par la commande suivante, où la limitation ^est supprimée:

grep -Po 'Logfile started :\K.*' process.log

Les objectifs ci-dessus pourraient également être atteints par des sedgroupes de capture ()->\1:

sed -nr 's/^.*Logfile started :(.*)$/\1/p' process.log

Où l'expression ^.*<something>.*$correspondra à toute la ligne, qui contient <something>. La commande s/old/new/remplacera cette ligne par le contenu du premier groupe de capture (l'expression entre crochets pourrait être plus concrète). L'option -ractive les expressions régulières étendues. L'option -nsupprimera la sortie normale de sedet enfin la commande paffichera les correspondances.

pa4080
la source
Je ne savais pas qu'il awkpouvait y avoir un FS multi-caractères avec des caractères avec une signification spéciale! Chose que j'ai apprise aujourd'hui.
Floris
6

Puisque vous traitez déjà cela awk, vous pouvez aussi bien faire le tout directement:

$ echo "foo bar :29.06.2019 23:03:17" |  awk '{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Le subformat général de la commande est sub(/REGEX/, REPLACEMENT, TARGET)et remplacera toutes les correspondances de l'expression régulière REGEXpar la chaîne REPLACEMENTdans la chaîne d'entrée TARGET. Ici, nous remplaçons le premier :( ^signifie "le début") du 3e champ ( $3) par rien.

Bien sûr, si vous faites cela dans awk, vous pouvez aussi bien tout faire dans awk et faire le tout en une seule opération:

$ echo "Logfile started :29.06.2019 23:03:17" | 
    awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Ou, dans votre cas:

TDS="$(awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' process.log)"
echo "$TDS"
terdon
la source
0

Une autre solution bash:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Cela utilise le pipeline au lieu d'une affectation de variable intermédiaire.
  • La commande xargsconvertit stdin(entrée standard) en paramètres positionnels pour la bashcommande.
  • Remplacez echopar tail -n1 /path/to/reportfile.txt.
WinEunuuchs2Unix
la source