Temukan semua filename.ext1 di mana tidak ada filename.ext2 di OS X atau shell


5

Saya perlu membuat versi TIF dan JPG dari serangkaian besar gambar.

Semua gambar JPG sudah ada, tetapi hanya sebagian dari gambar TIF. Apakah ada cara mudah untuk mencari direktori untuk menemukan semua file JPG yang tidak memiliki file TIF yang sesuai (mis. File dengan nama yang sama tetapi dengan ekstensi file yang berbeda)?


Seandainya saya melihat ini sebelumnya, mengajukan pertanyaan serupa hari ini.
Rob

Jawaban:


3

Perl one-liner:

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

Dalam 63 karakter:

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

Menarik ... Tapi ketika saya mencobanya saya mendapat kesalahan berikut (harap dicatat bahwa saya tidak tahu perl sama sekali ...): Anderss-MacBook-Pro: Temp Anders $ perl hello.pl String ditemukan di mana operator diharapkan hello.pl baris 2, dekat "nama ' .jpg '"(Apakah Anda perlu menentukan nama?) String ditemukan di tempat yang diharapkan operator di hello.pl baris 2, di dekat" pnle' s / .jpg //; - f "$ _. tif" || "$ _. jpg "'" (Apakah Anda perlu memprediksikan pnle?) kesalahan sintaks di hello.pl baris 2, dekat "name' .jpg '"Eksekusi hello.pl dibatalkan karena kesalahan kompilasi.
Anders Svensson

Saya kira Anda baru saja meninggalkan sesuatu yang Anda kira saya akan tahu :-). BTW, apakah ada cara untuk membuat rekursif ini untuk memeriksa subdirektori juga, dengan nama direktori yang dicetak?
Anders Svensson

Woops, Anda menjalankan ini dari baris perintah, bukan dari dalam skrip perl. Cukup potong dan tempel ke terminal ketika Anda berada di direktori dengan gambar. Ini harus mencakup subdirektori, tetapi daftar file sebagai "direktori / file1", "direktori / file2", dll.
barrycarter

Ok, itu cukup bagus! Sebenarnya, hanya yang pertama yang bekerja, bukan yang kedua. Yang itu hanya mendaftar semua file ... Bukankah Anda bisa menjalankan ini dalam file? Saya membaca pengantar singkat singkat untuk perl, tempat Anda meletakkan skrip dalam file .pl dan menjalankannya dari Terminal. Itu akan baik untuk dimiliki jika saya perlu menggunakannya kembali, daripada harus menyisipkan ini setiap kali ... Terima kasih
Anders Svensson

Ya, saya menyadari kemudian bahwa yang kedua rusak. Ini benar-benar kombinasi dari perintah dan perl Unix. Jika mau, Anda dapat meletakkannya file yang bernama "something.sh" dan kemudian melakukan "sh something.sh" (atau "bash something.sh"). Jika Anda memiliki 'convert' (ImageMagick), Anda bahkan dapat mengubah jpg menjadi tiff.
barrycarter

7

Dengan asumsi semua gambar ada di images direktori dan memiliki .jpg akhiran, skrip kecil berikut akan mencetak semua file gambar yang tidak memiliki yang sesuai .tif file di 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

Rekatkan ini ke file, dan simpan folder di atas yang menyimpan gambar Anda. Anda bisa menyebutnya find-images. Sebagai contoh:

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

Sekarang buka Utilitas / Terminal.app , dan gunakan cd perintah untuk menavigasi ke folder tempat skrip Anda, mis. jika skrip ada di Desktop Anda, cukup masukkan cd Desktop.

Lalu, masuk chmod +x find-images. Sekarang Anda dapat menjalankan skrip hanya dengan menelepon ./find-images.


Oke, ini kedengarannya bisa dilakukan. Saya menggunakan Mac, yang merupakan jenis Unix, tapi saya benar-benar baru di Mac. Apakah saya meletakkan skrip ini di Terminal atau apakah saya entah bagaimana membuat file skrip (bash kurasa ...)?
Anders Svensson

@AndersSvensson Saya menambahkan beberapa informasi tentang cara menjalankannya. KAK, harap Anda tidak keberatan.
slhck

Ini berfungsi dengan baik, dan cukup sederhana, terima kasih. Hanya pertanyaan lanjutan: apakah ada cara sederhana untuk membuatnya rekursif, dan periksa semua subdirektori juga? Lebih disukai mencetak nama direktori, seperti di bagian file hasil?
Anders Svensson

Maaf, baru saja perhatikan itu benar-benar memeriksa secara rekursif ... Hanya jalankan di folder tes pertama yang tidak memiliki subdirs ... Saya masih harus memilih solusi perl, karena itu bekerja dengan semua file, yang ini gagal pada file dengan spasi di namanya. Terimakasih Meskipun.
Anders Svensson

Sslhck, jangan khawatir.
Kusalananda

6

Saya akan menggunakan Python, karena ini adalah cross-platform. Pertama-tama, letakkan file jpg dan tif Anda di folder terpisah.

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

Kemudian, simpan skrip ini ke file, di suatu tempat di hard drive Anda, mungkin dengan namanya find-images.

Sekarang buka Utilitas / Terminal.app , dan masuk python /path/to/file. Misalnya, jika Anda menyimpannya di Desktop, itu akan menjadi python ~/Desktop/find-images (sejak ~ adalah jalan pintas ke folder rumah Anda). Di sini, Anda bisa berlari penjelasan yang lebih rinci menjalankan file Python di Mac Anda.


3
Anda harus menghapus ekstensi file terlebih dahulu, jika tidak tidak ada file akan cocok. Saya akan menebak [item.rsplit(".", 1)[0] for item in os.listdir(jpgPath)]...
grawity

Hmm, oke terima kasih, tapi saya tidak tahu cara menggunakan Python. Saya menggunakan Mac, apakah Python akan berfungsi di Terminal, atau apa yang harus saya lakukan? @grawity: dan di mana saya akan menempatkan pengupasan perintah ekstensi ini?
Anders Svensson

@ kegembiraan Oh benar. Saya konyol. Diedit. @AndersSvensson Python harus diinstal sebelumnya pada mac Anda. Ketik saja python ke Terminal dan rekatkan pada kode di atas.
Samuel

2

Ah, saya ingin menambahkan ini. Inilah solusi di Ruby, yang mencetak setiap gambar yang tidak memiliki rekanan TIF:

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

Masukkan ke dalam file yang berada di folder yang sama dengan gambar Anda, simpan sebagai find-images, dan jalankan di Terminal dengan memasukkan ruby find-images.

Jika Anda tidak tahu Ruby, jangan tanya bagaimana cara kerjanya, mungkin perlu waktu untuk menjelaskan: P


1
Versi yang lebih umum: 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. Cukup rapi. Masih belajar - tugas paralel adalah sesuatu yang harus saya gunakan lebih sering.
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
  • Pemakaian: cd somedir; diffext jpg tif
  • Mencari secara rekursif dalam subdirektori dari direktori saat ini
    • Memperlakukan file sebagai duplikat walaupun mereka berada di direktori yang berbeda

1

Satu liner tanpa perl:

Dengan menggunakan while loop setelah ditemukan:

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

Dengan menggunakan (banyak) subshell:

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

Ini akan bekerja dengan nama file yang memiliki spasi dan mencetak jalur absolut: diffexts() { find "$PWD" -name "*.$1" | while read f; do [[ ! -e ${f%.$1}.$2 ]] && echo "$f"; done; }
Lri
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.