awk sed si déclaration

J'essaie d'append 0 au début, s'il y a un "." au 2ème caractère de cette ligne. Je ne pouvais pas combiner ces deux;

awk '{ print substr( $0, 2, 1 ) }' file.txt 

montrant le deuxième caractère

 sed -ie "s/.\{0\}/0/" file.txt 

en ajoutant un zéro au début.

Il devrait y avoir un "si le deuxième caractère est un point".

file d'exemple:

 1.02.2017 23:40:00 10.02.2017 23:40:00 

final:

 01.02.2017 23:40:00 10.02.2017 23:40:00 

Nous pouvons utiliser sed ou awk pour résoudre complètement le problème.


Avec sed :

 $ sed 's/^.\./0&/' file.txt 

Quand & se produit dans la partie de rlocation des commands de substitution, elle sera étendue à la partie de la ligne d'input qui correspond à la partie de motif de la command.

L'expression régulière ^.\. signifie "faire correspondre toutes les lignes qui commence par ( ^ ) un caractère arbitraire ( . ) suivi d'un point littéral ( \. ) ".

Si la ligne est 1.02.2017 23:40:00 , le motif correspondra et 1. sera remplacé par 01. au début de la ligne.


Avec awk :

En s'appuyant sur le code partiel awk dans la question …

Ceci, comme indiqué, imprimera le deuxième caractère de chaque ligne d'input:

 $ awk '{ print substr($0, 2, 1) }' file.txt 

Nous pouvons utiliser le fait que substr($0, 2, 1) renvoie le second caractère et l'utilise comme condition:

 $ awk 'substr($0, 2, 1) == "." { ... }' file.txt 

Ce qui se passe dans { ... } est le code précédant $0 , qui est le contenu de la ligne courante, avec un zéro si la condition précédente est vraie:

 $ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt 

Ensuite, il suffit de s'assurer que toutes les lignes sont imprimées:

 $ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt 

La condition substr($0, 2, 1) == "." peut bien sûr être changé en une expression régulière aussi (nous utilisons exactement la même expression que celle utilisée dans la solution sed ):

 $ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt 

Certaines personnes qui pensent que "plus courte est toujours mieux" écrirait que

 $ awk '/^.\./ { $0 = "0" $0 } 1' file.txt 

(et probablement aussi supprimer la plupart des espaces: awk '/^.\./{$0="0"$0}1' file.txt )

Avec sed:

 sed -e "/^.\./s/^/0/" file.txt 

Le motif / /^.\./

L'expression sed s/.\{0\}/0/ est quelque peu étrange, elle correspond à zéro ou plus de copys et remplace par zéro. Bien entendu, le motif correspondra dans toutes les positions de la string, mais puisque s/// ne remplace que la première, il fonctionne comme prévu. Une façon pittoresque de le faire, cependant.


Ou avec awk, une regex similaire fonctionnerait pour correspondre à la ligne, mais nous pouvons utiliser substr :

 awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt 

Nous testons d'abord si le deuxième caractère est un point, puis ajoutez un zéro à l'avant de la ligne si c'est le cas. Le dernier invoque l'action par défaut de l'printing de la ligne après toute modification.

Vous avez dit awk et sed, mais il semble que vous essayez de formater une date et pour cela j'utiliserais la command date . Par exemple:

 echo '1.2.2017 23:40:00' | sed 's/\./\//g' | xargs -0 date '+%m.%d.%Y %T' -d 

sortira

 01.02.2017 23:40:00 

La command sed au milieu change les périodes en barres pour l'input dans la date -d . Les options de format permettent la sortie dans presque n'importe quel format que vous voulez. Le %m en particulier sera zéro-pad le mois, ce qui est ce que vous semblez essayer.

Comme le souligne Kusalananda:

Encore plus compact (date GNU et Bash): date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'

Une stratégie différente de celle présentée dans les autres réponses: Vous pourriez utiliser "." comme séparateur de champs.

 awk -F. '$1 < 10 {printf "0"} {print}' /tmp/in.txt 

Vous pourriez golfer ceci à:

 awk -F. '$1<10{printf "0"}1' /tmp/in.txt 

Pour sed, il y a une command plus courte, présentée dans une autre (grande) réponse.

Avec sed ça pourrait être

 sed 's/^\(.\)\.\(.*\)/0\1.\2/' 

Ceci utilisera ^ pour ancrer au début de la ligne, puis capturer n'importe quel caractère dans un groupe, suivi d'un littéral . , puis tout le rest. Si nous faisons correspondre cela, nous imprimons un 0 , puis notre premier groupe de capture (le caractère au début de la ligne), puis a . puis notre deuxième groupe de capture (le rest de la ligne)