Utilisez bash, comment filtrer par n caractères dans le cycle `for`

0

Problème

J'ai besoin de filtrer les fichiers de la sortie par les 12 premiers caractères, puis de les envoyer en tant que sortie de la ffmpegcommande, puis de le refaire pour le cycle suivant.

Fichier d'entrée.

VID_20190920_195919.mp4
VID_20190920_200821.mp4
VID_20190920_221640.mp4
VID_20190921_141929.mp4
VID_20190921_142236.mp4

Sortie filtrée au 1er cycle (par 12 premiers caractères, donc par VID_20190920).

VID_20190920_195919.mp4
VID_20190920_200821.mp4
VID_20190920_221640.mp4

Sortie filtrée au 2e cycle (par les 12 premiers caractères, donc par VID_20190921).

VID_20190921_141929.mp4
VID_20190921_142236.mp4

etc.

Chaque cycle (liste de fichiers filtrés) doit être exporté cycle.txt, puis le fichier doit être traité par cette commande.

ffmpeg -f concat -i cycle.txt -c copy VID_YYYYMMRR.mp4

Ensuite , nettoyez cycle.txtpar > cycle.txtet le faire à nouveau pour le prochain cycle.

Ou est la meilleure façon de faire cela?

Merci.

Système

Linux local 5.0.0-29-lowlatency #31-Ubuntu SMP PREEMPT Thu Sep 12 14:13:01 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
genre
la source
Le "20" et le "21" sont fixes ou pourraient être n'importe quel autre nombre?
Guillermo Chamorro
@guillermochamorro Il y a plus de dates, par exemple VID_20190820*, VID_20190825*etc. J'ai donc besoin de greptous les fichiers avec ce caractère sur begin et je l'écris dans file. J'ai essayé cut -c 1-12, mais il n'y a aucun moyen d'afficher le nom complet du fichier dans ce cas. Ou peut-être que je peux utiliser cut -c 1-12 | sort -n | uniqsur cette sortie et ensuite utiliser forpour cette sortie. Mais y a-t-il une meilleure façon de le faire?
genderbee le

Réponses:

0

En supposant que vos fichiers vidéo se trouvent dans le même répertoire, vous pouvez utiliser les commandes bash suivantes:

for i in VID_*.mp4; do
  echo ${i%_*}
done | sort -u | while read f; do
  ffmpeg -f concat -i <(echo ${f}*) -c copy "${f}.mp4"  
done

Le script récupère toutes les vidéos VID_*.mp4et supprime le suffixe _XXX.mp4du nom.
Puis, parcourez tous les noms uniques du formulaire VID_XXXet exécutez la commande ffmpeg.

oliv
la source
Semble mieux que 2 forboucles comme j'ai essayé, mais erreur [concat @ 0x555e24bd9940] Line 1: unknown keyword 'VID_20190921_141929.mp4' /dev/fd/63: Invalid data found when processing input. Où est la prise? J'ai essayé ffmpeg -f concat -safe 0 -i <(echo ${f}*) -c copy "${f}.mp4"aussi.
genderbee le
@genderbee Votre ffmpegcommande fonctionne- t-elle si vous ajoutez manuellement les noms de fichiers dans votre cycle.txt?
oliv
Oui, mais c'est nécessaire en format file 'VID_YYYYMMDD*'. J'ai essayé ffmpeg -f concat -safe 0 -i <(echo "file '${f}*'") -c copy "${f}.mp4", mais j'ai probablement fait quelque chose de mal.
genderbee le
0

Je pense que cela peut faire:

unique=($(cat foo | cut -c 5-12 | sort -u))

for i in "${!unique[@]}"; do 
  find *${unique[$i]}* > cycle_$i
done

Créez un tableau avec seulement les dates:

unique=($(cat foo | cut -c 5-12 | sort -u))

Parcourez le tableau, recherchez les fichiers correspondant à chaque date et enregistrez la sortie dans un fichier avec un nom d'index:

for i in "${!unique[@]}"; do 
  find *${unique[$i]}* > cycle_$i
done

Résultat:

cycle_0.txt

VID_20190920_195919.mp4
VID_20190920_200821.mp4
VID_20190920_221640.mp4

cycle_1.txt

VID_20190921_141929.mp4
VID_20190921_142236.mp4
guillermo chamorro
la source
0

À la fin, cette solution fonctionne.

chars=12
    for file in $(find . -name '*.mp4' -printf "%f\n" | sort -n | cut -c 1-$chars | uniq)
    do
        find . -name '*.mp4' | grep $file | sed "s/^/file '/" | sed "s/$/'/" | sort -n > filein
        ffmpeg -v quiet -safe 0 -f concat -i filein -c copy $file.mp4
    done

Il semble que l'exportation dans un fichier est nécessaire. Ou pas?

Info.

chars, nombre de mêmes personnages à rejoindre.

Vous pouvez ajouter -mindepth -maxdepthà la findcommande, pour la profondeur du dossier.

genre
la source