1
votes

Pourquoi sed renvoie plus de caractères que demandé

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.

sed

2 commentaires

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.


3 Réponses :


0
votes

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 ... .


1 commentaires

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. :)



0
votes

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


1 commentaires

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.



0
votes

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.


1 commentaires

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. :)