Python'da uzantı olmayan dosya türleri nasıl kontrol edilir?


87

Dosyalarla dolu bir klasörüm var ve bunların bir uzantısı yok. Dosya türlerini nasıl kontrol edebilirim? Dosya türünü kontrol etmek ve dosya adını buna göre değiştirmek istiyorum. Bir işlevin filetype(x)gibi bir dosya türü döndürdüğünü varsayalım png. Bunu yapmak istiyorum:

files = os.listdir(".")
for f in files:
    os.rename(f, f+filetype(f))

Bunu nasıl yaparım?



Daha spesifik olmalısın file types. Bir gif, png, bmp veya jpg olup olmadığını belirlemeyi mi kastediyorsunuz? Sadece metin / ikili olup olmadığını mı öğrenmek istiyorsunuz? Yürütülebilir mi?
JoeFish

@ thg435, MIME türüne sahip olduğunuzda, bunu uygun bir dosya adı uzantısına dönüştürmenin bir yolu var mı?
Mark Ransom

@Mark: evet, tahmin_uzantısı kullanın , ancak aslında mime türleri burada çalışmaz, çünkü dosya uzantılarına dayalıdır. İhtiyaç duydukları şey libmagic (bağlantıdaki 2. cevaba bakın).
georg

Yanıtlar:


92

Dosyaları içeriklerine göre (genellikle bir başlık / sihirli sayı) tanıyan ve dosya adına veya uzantısına dayanmayan Python kitaplıkları vardır.

Birçok farklı dosya türünü ele alıyorsanız, kullanabilirsiniz python-magic. Bu sadece iyi kurulmuş magickütüphane için bir Python bağlantısıdır . Bunun iyi bir ünü var ve (küçük bir onay) yaptığım sınırlı kullanımda, sağlam oldu.

Daha özel dosya türleri için kitaplıklar da vardır. Örneğin, Python standart kitaplığı, imghdrsadece görüntü dosyası türleri için aynı şeyi yapan bir modüle sahiptir .

Bağımlılık içermeyen (saf Python) dosya türü kontrolüne ihtiyacınız varsa, bakın filetype.


2
Paket python-magic-win64benim için Windows'ta çalıştı
ChesuCR

2
dosya türü kombinasyonu ile imghdr benim için Windows'ta çalıştı
Hrushikesh Dhumal

62

Python Sihirli kütüphanesi ihtiyacınız işlevsellik sağlar.

Kitaplığı ile kurabilir ve pip install python-magicaşağıdaki gibi kullanabilirsiniz:

>>> import magic

>>> magic.from_file('iceland.jpg')
'JPEG image data, JFIF standard 1.01'

>>> magic.from_file('iceland.jpg', mime=True)
'image/jpeg'

>>> magic.from_file('greenland.png')
'PNG image data, 600 x 1000, 8-bit colormap, non-interlaced'

>>> magic.from_file('greenland.png', mime=True)
'image/png'

Bu durumda Python kodu , * NIX komutu tarafından kullanılan aynı kitaplık olan kaputun altındaki libmagic'i çağırıyor file. Bu nedenle, bu, alt süreç / kabuk tabanlı yanıtlarla aynı şeyi yapar, ancak bu ek yük olmadan.


6
Python-magic adlı debian / ubuntu paketinin aynı adlı pip paketinden farklı olduğuna dikkat edin. Her ikisi de import magicancak uyumsuz içeriğe sahip. Daha fazla bilgi için stackoverflow.com/a/16203777/3189 sayfasına bakın .
Hamish Downer

1
@Richard Genel gider yönünü detaylandırır mısınız? python-magicKütüphaneyi alt süreç yaklaşımlarından daha verimli kılan nedir ?
Greg

9

Unix ve linux'ta filedosya türlerini tahmin etme komutu vardır. Bir pencere bağlantı noktası bile var .

Gönderen adam sayfası :

Dosya, her bir bağımsız değişkeni sınıflandırmak için test eder. Bu sırayla gerçekleştirilen üç test grubu vardır: dosya sistemi testleri, sihirli sayı testleri ve dil testleri. Başarılı olan ilk test, dosya türünün yazdırılmasına neden olur.

fileKomutu subprocessmodülle çalıştırmanız ve ardından bir uzantı bulmak için sonuçları ayrıştırmanız gerekir.

düzenleme: Cevabımı göz ardı et. Bunun yerine Chris Johnson'ın cevabını kullanın.


+1 fileO kadar çok şey yaptığını bilmiyordum . # file arc.gif arc.gif: GIF image data, version 89a, 234 x 269
JoeFish

Birinin daha iyi bir cevabı olduğunu umuyordum. OP için hala çok iş var, bu basit bir işlev çağrısı değil.
Steven Rumbalski

2
+1 fileKomutu kullanmanın bir avantajı, Linux dağıtımlarında yerel python-magicolması ve kullanılmadan önce indirilip yüklenmesi gerekmesidir. Modülü kullanan betiğin taşınabilir olması bekleniyorsa, bu biraz problemdir.
HelloGoodbye

7

Görüntüler durumunda, imghdrmodülü kullanabilirsiniz .

>>> import imghdr
>>> imghdr.what('8e5d7e9d873e2a9db0e31f9dfc11cf47')  # You can pass a file name or a file object as first param. See doc for optional 2nd param.
'png'

Python 2 imghdr doc
Python 3 imghdr doc



6
import subprocess
p = sub.Popen('file yourfile.txt', stdout=sub.PIPE, stderr=sub.PIPE)
output, errors = p.communicate()
print(output)

Steven'ın işaret ettiği gibi subprocess, yol bu. Bu yazının dediği gibi komut çıktısını yukarıdaki şekilde alabilirsiniz


Ve çıktıyı nasıl yakalarsınız?
Mark Ransom

@MarkRansom üzgünüm bu iyi bir yol değildi, lütfen yukarıdaki güncellemelerime bakın
xvatar

Bir Python kitaplığı kullanmak yerine sisteminizle etkileşime girmeniz gerekiyorsa, çözüm çoğu zaman yetersizdir çünkü muhtemelen farklı bir API'ye sahip diğer işletim sistemlerinde yararlı değildir.
erikbwork

4

Daha yeni alt işlem kitaplığıyla, artık aşağıdaki kodu kullanabilirsiniz (* yalnızca nix çözümü):

import subprocess
import shlex

filename = 'your_file'
cmd = shlex.split('file --mime-type {0}'.format(filename))
result = subprocess.check_output(cmd)
mime_type = result.split()[-1]
print mime_type

Cevap için teşekkürler. BTW, cmd satırında str.split () kullanmamalısınız. shlex.split (cmd) insteed kullanın.
emnoor

Kullanmak yerine shlex.splitneden koşmuyorsunuz subprocess.check_output(['file', '--mime-type', filename])?
Flimm

1

ayrıca bu kodu da kullanabilirsiniz (saf python, 3 bayt başlık dosyası):

full_path = os.path.join(MEDIA_ROOT, pathfile)

try:
    image_data = open(full_path, "rb").read()
except IOError:
    return "Incorrect Request :( !!!"

header_byte = image_data[0:3].encode("hex").lower()

if header_byte == '474946':
    return "image/gif"
elif header_byte == '89504e':
    return "image/png"
elif header_byte == 'ffd8ff':
    return "image/jpeg"
else:
    return "binary file"

herhangi bir paket yüklemesi olmadan [ve sürümü güncelle]


Xlsx'i nasıl kontrol edebilirim?
Harsha Biyani

4 veya 8 bayt kullanabilirsiniz. XLSX (MS Office Açık XML Biçimli Belge) => 50 4B 03 04 (4 Bayt) => ASCII (PK ••) veya XLSX (MS Office 2007 belgeleri) => 50 4B 03 04 14 00 06 00 (8 Bayt) = > ASCII (PK ••••••)
Evergreen

0

Yalnızca Linux için çalışır, ancak "sh" python modülünü kullanarak herhangi bir kabuk komutunu çağırabilirsiniz.

https://pypi.org/project/sh/

pip yüklemek sh

sh ithal

sh.file ("/ kök / dosya")

Çıktı: / kök / dosya: ASCII metni

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.