Rechercher tous les fichiers.ext1 où aucun fichier.ext2 n'existe dans OS X ou dans le shell


5

Je dois créer à la fois des versions TIF et JPG d'un grand ensemble d'images.

Toutes les images JPG existent déjà, mais seulement une partie des images TIF. Existe-t-il un moyen simple de rechercher dans un répertoire tous les fichiers JPG n’ayant pas de fichier TIF correspondant (c’est-à-dire un fichier du même nom mais avec une extension différente)?


J'aurais aimé voir cela plus tôt, posé une question similaire aujourd'hui.
Rob

Réponses:


3

Perl one-liner:

find . -name '*.jpg'|perl -nle 's/\.jpg//;unless(-f "$_.tif"){print "$_.jpg"}' 

En 63 caractères:

find . -name '*.jpg'|perl -pnle 's/.jpg//;-f "$_.tif"||"$_.jpg"' 

Intéressant ... Mais quand j'ai essayé, j'ai eu l'erreur suivante (notez que je ne connais pas du tout perl ...): Anderss-MacBook-Pro: Temp Anders $ perl hello.pl Chaîne trouvée là où l'opérateur était attendu à hello.pl ligne 2, près de "nom" .jpg '"(Avez-vous besoin de déclarer le nom à l'avance?) Chaîne trouvée là où l'opérateur est attendu sur la ligne 2 de hello.pl, près de" pnle's / .jpg //; -f "$ _. tif" || "$ _. jpg "'" (Avez-vous besoin de prédéclarer un pnle?) erreur de syntaxe à la ligne 2 de hello.pl, près de "nom" .jpg '"L' exécution de hello.pl a été annulée en raison d 'erreurs de compilation.
Anders Svensson

Je suppose que vous venez de laisser de côté quelque chose que vous pensiez connaître, je suppose :-). BTW, y a-t-il un moyen de rendre cela récursif pour vérifier également les sous-répertoires, avec les noms de répertoires imprimés?
Anders Svensson

Woops, vous exécutez ceci à partir de la ligne de commande, pas à l'intérieur d'un script Perl. Il suffit de couper et coller dans le terminal lorsque vous êtes dans le répertoire w / les images. Cela devrait couvrir les sous-répertoires, mais la liste des fichiers comme "répertoire / fichier1", "répertoire / fichier2", etc.
barrycarter

Ok, c'est plutôt sympa! En réalité, seul le premier fonctionnait bien, pas le second. Celui-ci ne répertorie que tous les fichiers ... Ne devriez-vous pas pouvoir l'exécuter dans un fichier? J'ai lu une introduction vraiment courte en perl, dans laquelle vous avez placé le script dans un fichier .pl et que vous l'avez exécuté à partir de Terminal. Ce serait bien d'avoir au cas où je devrais le réutiliser, au lieu d'avoir à le coller à chaque fois ... Merci
Anders Svensson

Oui, j'ai réalisé plus tard que le second était cassé. C'est vraiment une combinaison de commandes Unix et de Perl. Si vous le souhaitez, vous pouvez placer un fichier nommé "quelquechose.sh" et ensuite "sh quelque chose.sh" (ou "bash quelque chose.sh"). Si vous avez 'converti' (ImageMagick), vous pouvez même convertir les jpgs en tiffs.
barrycarter

7

En supposant que toutes les images sont dans le images répertoire et a la .jpg suffixe, le petit script suivant imprimera tous les fichiers d’image n’ayant pas de correspondance .tif fichier sur UNIX:

#!/bin/sh

find images/ -type f -name "*.jpg" |
while read j; do
  t=${j%.jpg}.tif
  if [ ! -f "$t" ]; then
    echo "Lacking tif file: " $j
  fi
done

Collez-le dans un fichier et enregistrez-le dans un dossier situé au-dessus de celui dans lequel vos images sont stockées. Vous pourriez l'appeler find-images. Par exemple:

├── find-images
└── images/
    ├── 1.jpg
    └── 2.jpg
    └── ...

Ouvert Utilitaires / Terminal.app et utiliser le cd commande pour accéder au dossier où se trouve votre script, par exemple. si le script est sur votre bureau, entrez simplement cd Desktop.

Puis entrez chmod +x find-images. Maintenant, vous pouvez exécuter le script en appelant simplement ./find-images.


Ok, cela semble faisable. Je suis sur un Mac, qui est une sorte d'Unix, mais je suis vraiment nouveau sur Mac. Est-ce que je mets ce script dans Terminal ou est-ce que je crée en quelque sorte un fichier de script (bash je suppose ...)?
Anders Svensson

@ AndersSvensson, j'ai ajouté quelques informations sur la façon de l'exécuter. KAK, espérons que cela ne vous dérange pas.
slhck

Cela fonctionne bien, et assez simple, merci. Juste une question de suivi: existe-t-il un moyen simple de le rendre récursif et de vérifier également tous les sous-répertoires? De préférence, afficher le nom du répertoire, comme dans les sections du fichier de résultat?
Anders Svensson

Désolé, j'ai remarqué qu'il vérifie récursivement ... Il suffit de l'exécuter d'abord sur un dossier de test sans sous-répertoires ... Je dois toujours choisir la solution Perl, car cela fonctionnait avec tous les fichiers, celui-ci échouant avec des espaces dans les noms. Merci quand même.
Anders Svensson

@slhck, pas de soucis.
Kusalananda

6

Je vais utiliser Python, car il est multi-plateforme. Commencez par placer vos fichiers jpg et tif dans des dossiers distincts.

import os

jpgPath = "path/to/jpgs/folder"
tifPath = "path/to/tifs/folder"

jpgList = [item.rsplit(".", 1)[0] for item in os.listdir(jpgPath)]
tifList = [item.rsplit(".", 1)[0] for item in os.listdir(tifPath)]

diffList = [item for item in jpgList if item not in tifList]

print diffList

Enregistrez ensuite ce script dans un fichier, quelque part sur votre disque dur, éventuellement sous le nom find-images.

Ouvert Utilitaires / Terminal.app et entrez python /path/to/file. Par exemple, si vous l’avez sauvegardé sur votre bureau, ce serait python ~/Desktop/find-images (puisque ~ est un raccourci vers votre dossier personnel). Ici, vous pouvez courir une explication plus détaillée sur l'exécution de fichiers Python sur votre Mac.


3
Vous devez d'abord supprimer les extensions de fichier, sinon aucun des fichiers correspondra. Je dirais [item.rsplit(".", 1)[0] for item in os.listdir(jpgPath)]...
grawity

Hmm, d'accord merci, mais je ne sais pas comment utiliser Python. Je suis sur Mac, Python fonctionne-t-il dans Terminal ou que dois-je faire? @grawity: et où placerais-je cette suppression de la commande extensions?
Anders Svensson

@grawity Oh oui. Que je suis bête. Édité. @AndersSvensson Python devrait être pré-installé sur votre mac. Il suffit de taper python dans Terminal et collez le code ci-dessus.
Samuel

2

Ah, j'ai eu envie d'ajouter ceci. Voici la solution Ruby, qui imprime toutes les images sans contrepartie TIF:

jpg = Dir["*.jpg"]
tif = Dir["*.tif"]    
[jpg, tif].each { |a| a.map!{ |f| f[0..-5]} }
puts jpg - tif

Placez-le dans un fichier qui se trouve dans le même dossier que vos images, enregistrez-le sous. find-imageset exécutez-le dans Terminal en entrant ruby find-images.

Si vous ne connaissez pas Ruby, ne demandez pas comment cela fonctionne, cela peut prendre un certain temps pour expliquer: P


1
Une version plus générique: a0, a1 = ARGV[0], ARGV[1]; dir0 = Dir["*.#{a0}"]; dir1 = Dir["*.#{a1}"]; dir0.each {|f| puts f unless dir1.include?(f.sub(/\.#{a0}$/, ".#{a1}"))}
Lri

@Lri Hah. Génial. J'apprends toujours - la tâche parallèle est quelque chose que je dois utiliser plus souvent.
slhck

2

diffext

#!/bin/bash

found1=$(find "$PWD" -name "*.$1")
found2=$(find "$PWD" -name "*.$2")
export IFS=$'\n'
for f1 in "$found1"; do
    base1=${f1##/}
    for f2 in "$found2"; do
        base2=${f2##/}
        [[ ${base1%.$1} == ${base2%.$2} ]] && continue 2
    done
    echo "$f1"
done
  • Usage: cd somedir; diffext jpg tif
  • Recherche récursivement dans les sous-répertoires du répertoire en cours
    • Traite les fichiers comme des doublons même s'ils se trouvaient dans des répertoires différents

1

One-Liner (s) sans perl:

Avec using while loop after find:

find . -name '*.jpg' | while read file ; do test ! -f `dirname $file`/`basename $file .jpg`.tif && echo $file; done

Avec l'utilisation de (beaucoup de) sous-coques:

find . -name '*.jpg' -exec sh -c 'test ! -f `echo {} |sed s/\.jpg$/.flac/` && echo {}' \;

Cela fonctionnerait avec les noms de fichiers comportant des espaces et imprimant les chemins absolus: diffexts() { find "$PWD" -name "*.$1" | while read f; do [[ ! -e ${f%.$1}.$2 ]] && echo "$f"; done; }
Lri
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.