Dans une partie de mon script, j'essaye de générer une liste de l'année et du mois où un fichier a été soumis. Puisque le fichier contient l'horodatage, je devrais pouvoir couper les noms de fichiers à la position du mois, puis effectuer un filtrage tri + uniq. Cependant sed génère une valeur aberrante pour l'un des fichiers.
J'utilise cette séquence de commandes
ls -1 service*json | sed -e "s|\(.*201.\{3\}\).*json$|\1|g" | sort |uniq
Et cela fonctionne la plupart du temps sauf dans certains cas horodatage complet:
$ ls service-parent-20181119092630.json service-parent-20181123134132.json service-parent-20181202124532.json service-parent-20190121091830.json service-parent-20190125124209.json service-parent-20181119101003.json service-parent-20181126104300.json service-parent-20181211095939.json service-parent-20190121092453.json service-parent-20190128163539.json service-parent-20181120095850.json service-parent-20181127083441.json service-parent-20190107035508.json service-parent-20190122093608.json service-parent-20181120104838.json service-parent-20181129155835.json service-parent-20190107042234.json service-parent-20190122115053.json $ ls -1 service*json | sed -e "s|\(.*201...\).*json$|\1|g" | sort |uniq service-parent-201811 service-parent-201811201048 service-parent-201812 service-parent-201901
J'ai également essayé cette variante mais la deuxième ligne de sortie est toujours renvoyée:
ls -1 service*json | sed -e "s|\(.*201...\).*json$|\1|g" | sort |uniq
Quelqu'un peut-il expliquer pourquoi service-parent-201811201048 est renvoyé au-delà des 3 caractères demandés?
Merci.
3 Réponses :
service-parent-201811201048
se trouve avoir 201048
pour correspondre à 201 ...
.
Pourrait essayer ls -1 service * json | sed -e "s | \ (. * - 201 ... \). * json $ | \ 1 | g" | sort | uniq
pour demander un tiret -
avant 201 ...
.
Choisir cela comme la bonne réponse car cela explique pourquoi j'obtiens des résultats étranges. Merci de l'avoir signalé car mes yeux sont plus fatigués que je ne le pensais. :)
Il n'est pas recommandé d'analyser la sortie de ls
. Veuillez essayer à la place:
for i in service*json; do sed -e "s|^\(service-.*-201[0-9]\{3\}\).*json$|\1|g" <<< "$i" done | sort | uniq
Noté. L'exemple de syntaxe vise à simplifier le scénario que je peux recréer. J'utilise déjà une boucle pour filtrer les fichiers.
Votre problème est expliqué à l'adresse https://stackoverflow.com/a/54565973/1745001 (c'est-à-dire . *
est gourmand) mais essayez ceci:
$ ls | sed -E 's/(-[0-9]{6}).*/\1/' | sort -u service-parent-201811 service-parent-201812 service-parent-201901
Ce qui précède nécessite un sed qui prend en charge les ERE via -E
, par exemple GNU sed et OSX / BSD sed.
Merci, cela fonctionne aussi mais je dois sélectionner la réponse de @ packard-cpw car elle explique la raison de la sortie étrange. Être gourmand est un peu plus haut niveau pour les débutants des expressions rationnelles comme moi. :)
Quand vous dites
le fichier contient l'horodatage
- voulez-vous vraiment dire que le fichier nom contient l'horodatage? Cela ressemble à votre exemple, en vous assurant simplement ...Oui, ils le font. Les fichiers sont des extraits réguliers d'un système source et alimentés dans une base de données chronologique. Cependant, la base de données ne m'est pas accessible (c'est dans un VPN) mais j'ai accès aux fichiers d'extrait jusqu'à une certaine date.