Sed : extraction multiple

Bonjour,

contrairement à ce que je crois obtenir avec cette commande:
sed 's/.*\(VID.*mp4\).*$/\1\n/g' fichier.osp
elle ne renvoie que la première occurrence.
(le fichier ne fait qu’une très longue ligne: fichier openshot)

Je ne doute pas que l’erreur soit simple, mais j’avoue ne pas la trouver.

Et pour trouver les VID.*.mp3 et VID.*.mp4 :
sed 's/.*\(VID.*mp.\).*$/\1\n/g' fichier.osp
renvoie le fichier entier (ne supprime rien)

Après avoir oublié le peu qui me suffisait il y apas mal d’années sur sed et sur les regex, je ne m’y retrouve donc plus.

merci pour votre aide.

Bonjour,

Et si tu fais précéder ta règle de substitution par N ainsi :
sed 'N;s/.*\(VID.*mp.\).*$/\1\n/g' fichier.osp ?

je ne comprend pas cette syntaxe (N;), mais le résultat est l’affichage complet du fichier

wc -w fichier.osp

et
sed 'N;s/.*\(VID.*mp4\).*$/\1\n/g' fichier.osp | wc -w

donnent le même résultat:
636679 fichier.osp

Que fait N; ?

Cette syntaxe peut-être utile quand tu recherches/remplaces des retours à la ligne multiples.

Mais je pense que ton problème vient de la fin de ligne $ que tu indiques après .*. Sed va chercher éventuellement la première occurrence et s’arrêter là.
et si tu fais simplement : sed 's/\(mp[34]\)/\1\n/g' ? Tu auras déjà tous tes retours à la ligne et tu peux enchaîner ensuite d’autres substitutions, ce qui pourrait donner :
sed 's/\(mp[34]\)/\1\n/g' | sed 's/.*\(VID\)/\1'/

Bonjour

C’est très difficile de pouvoir faire une regex efficace sans savoir sur quoi elle va s’appliquer,
ça serait tellement plus facile si on avait un exemple ou mieux, le contenu du fichier.osp
avec lequel on pourrait faire des tests.

@MicP
Voici le fichier .osp
Printemps2020_Buster.bkp.osp.txt (5,4 Mo)

Le but est d’ extraire (dans l’ordre) la liste des fichiers jpg et mp4, pour reconstruire cette vidéo avec d’autres outils. (Le son n’a pas besoin d’être synchrone, la durée des jpg constante mais ajustable).

@ tous
J’ai commencé à ma replonger (en surface et brièvement) dans«Maîtrise des expressions régulières».
p95:

  1. la première reconnaissance gagne
  2. les quantificateurs sont avides

Je crois que l’expression est «avide» et qu’il faut donc envisager de remplacer le point dans «.*» par «ce qui n’est pas l’expression recherchée», ce qui signifie que j’ai encore mal compris ce que fait «/g» à la fin; au moins ce qu’il ne peut pas faire!.
Je continue de m’instruire et de tester (quand je peux), et vous en aviserai bien entendu.
merci à tous

Voici pour extraire dans l’ordre les liens vers les fichiers jpg et mp4 :

cat Printemps2020_Buster.bkp.osp | jq .[] | grep -iE '\.(jpg|mp4)' | sed 's/.*: "//;s/".*//'

Il faut installer jq pour reformater correctement ce fichier JSON.
Les mêmes champs ne sont malheureusement pas présents dans tous les objets. Dommage jq permet d’extraire facilement des informations de fichiers JSON. On ne pourra donc pas utiliser de façon plus poussée cet outil puissant.

Je viens de trouver celle là pour extraire tous les chemins
dont le nom d’extension est mp3 mp4 ou jpg

cat Printemps2020_Buster.bkp.osp | sed 's/path\": \"\([^"]*.mp[34]\|[^"]*.jpg\)/\n\1\n/g' | sed -n '/mp[34]$\|jpg$/p' | sort -u

831 chemins affichés en sortie triée sans doublons.

Merci beaucoup à tous les deux pour vos efforts et vos lumières.

Je ne connaissais pas jq, et ne connaissant rien à JSON, j’ignorais aussi que le fichier contenait une ligne ce format.

Malgré «sort -u», il reste des doublons, pas très difficiles à éliminer, autrement (avec uniq, par exemple) car sort modifie l’ordre initiale (très peu dans cet exemple, mais cette belle leçon resservira sans doute).

Les mêmes champs ne sont malheureusement pas présents dans tous les objets

Peut-être une observation à faire aux auteurs d’Openshot?

Ok, c’est peut-être une histoire de chemin relatif et absolu,
comme pour ces deux là :

/home/photos/Printemps2020_jardin/images/163-IMG_20200504_192733.jpg
../images/163-IMG_20200504_192733.jpg

=======
Un jour (peut-être), quand je saurai vraiment faire une vraie regex et utiliser awk
ma ligne de commande n’appellera plus qu’une seule commande
plutôt que d’utiliser 3 pipes, 2 sed et un sort

Un truc très pratique avec awk et que je n’ai appris qu’il y a peu de temps, c’est qu’il est capable de matcher des motifs
On peut aussi utiliser des variables dans les motifs, variables qui peuvent être des regex, même si la syntaxe s’alourdit un peu.

Par exemple:

sputnik93@debian-probook:~/workdir/debian_fr$ cat fichier.txt 
/chemin/toutou.mp3
/chemin3/sous-chemin/chatons.mp3
/autre/chemin/vacances.avi
/chemin/qsdbqb5.avi
/autre/chemin/jknqdjkBSD4.mp4

alex-epcc@debian-probook:~/workdir/debian_fr$ awk -F"/" -v motif="mp3|mp4" '$0 ~ motif {print $NF}' fichier.txt 
toutou.mp3
chatons.mp3
jknqdjkBSD4.mp4

Bref, awk est vraiment très puissant, on en apprend tous les jours dessus !

J’ai lu, il y a longtemps, qu’un service web permettait de construire et tester des regex en ligne.

En cherchant vite fait, j’ai trouvé celui là,

1 J'aime

grep + tr
si on a le droit à autre chose que sed :

cat Printemps2020_Buster.bkp.osp.txt |tr '"' '\n' |egrep "\.mp4$|\.mp3$"

cat Printemps2020_Buster.bkp.osp.txt |tr '"' '\n' |egrep "\.mp4$|\.mp3$|\.jpg$" |sort |uniq : 1237 fichiers

sauf que mp4.txt sort aussi de ton awk

le g à la fin répéte la recherche

cat fichier.txt
123a4b5cd6e78f9g
$ cat fichier.txt |sed "s#[^a-z]*##"
a4b5cd6e78f9g
$ cat fichier.txt |sed "s#[^a-z]*##g"
abcdefg

remarque j’utilise le dièze plutot que le slash, c’est mieux en bash à cause des slashs des dossiers

Merci Dindoun,
je savais que/g répétait la recherche, mais j’avais mal réfléchi au résultat (+ court!) (et pas seulement avec /g!)

Merci à tous

héhé
je m’en doutais un peu de ta part
mais c’était l’occasion de montrer du sed avec le dièze

Sinon, il y a aussi celui ci qui fait du bon boulot : https://ihateregex.io/expr/date

1 J'aime

Vertigineux !

Je vous invite à lire la page wikipédia Expression régulière
(que j’aurais plutôt nommée Expression rationnelle, mais bon …)


Et pour rester dans les expressions rationnelles, si vous utilisez awk
il faudra aussi faire attention au fait que la commande awk est souvent un lien vers le fichier

/etc/alternatives/awk

ce qui fait que sur un système debian
quand on utilise la commande awk dans une ligne de commande(s)
c’est l’exécutable mawk qui sera lancé,
mais si vous avez installé le paquetage gawk
ce sera gawk qui sera lancé

et si gawk on peut utiliser la classe de caractère [:digit:]
avec mawk il faudra utiliser [0-9]