ফাইলগুলি "বাইনারি" বা "পাঠ্য" হিসাবে শ্রেণিবদ্ধ করার জন্য কি কোনও সুবিধাজনক উপায় আছে?


35

স্ট্যান্ডার্ড ইউনিক্স ইউটিলিটিগুলি ফাইলটিকে "পাঠ্য" বা "বাইনারি" হিসাবে শ্রেণিবদ্ধ করতে পছন্দ করে grepএবং diffকিছু হিউরিস্টিক ব্যবহার করে। (উদাহরণস্বরূপ, grepআউটপুট যেমন লাইন অন্তর্ভুক্ত থাকতে পারে Binary file frobozz matches।)

zshঅনুরূপ "পাঠ্য / বাইনারি" শ্রেণিবিন্যাস সম্পাদনের জন্য কোনও স্ক্রিপ্টে আবেদন করা যায় এমন সুবিধাজনক পরীক্ষা আছে কি ? (অন্য কিছু মত grep '' somefile | grep -q Binary।)

(আমি বুঝতে পারি যে এ জাতীয় কোনও পরীক্ষা অগত্যা বৈজ্ঞানিক এবং তাই অসম্পূর্ণ হবে be)


10
fileএটি একটি স্ট্যান্ডার্ড ইউটিলিটি এবং এটির সর্বোচ্চ ক্ষমতার জন্য ফাইলের ধরন নির্ধারণের জন্য ফাইল ম্যাজিকের মাধ্যমে চলতে পারে। এটি বেশিরভাগ পাঠ্য বিন্যাসগুলি বলতে পারে এবং বাইনারি ফর্ম্যাটগুলিতে বেশ সুন্দর কাজ করে। আপনি যা করার চেষ্টা করছেন তা যদি কোনও ফাইল পাঠ্য হয় কি না তা যদি খুঁজে বের করা হয় তবে আপনার সেই কমান্ডটি আগ্রহী
ব্র্যাচলে

@ ব্র্যাচলে: কিছু সংস্করণ fileমুদ্রণ করবে যেমন shell script, কিছু ফাইলের জন্য আমি "পাঠ্য" হিসাবে শ্রেণিবদ্ধ হতে চাই। fileশুধু textবা মুদ্রণ করার উপায় আছে binary?
kjo

1
@ don_crissti এই প্রশ্নটি কেউ তার বাশ স্ক্রিপ্টটি ডিবাগ করার জন্য লোককে চেষ্টা করার বিষয়ে। স্ক্রিপ্টটি করার কথা হ'ল পাঠ্য সনাক্ত করা। তারা তাদের একটি cutআদেশে একটি সমস্যা নিয়ে শেষ হয়েছিল ।
ব্র্যাচলে

1
@ ডন_ক্রিসটি এই প্রশ্নের যে উত্তর রয়েছে সে ক্ষেত্রে একটি প্রশ্ন বি এর পক্ষে সর্বদা এটিকে বি-র সদৃশ করে তোলে না এমন কেউ বিবেচনা করুন যিনি ফাইলকে পাঠ্য বা বাইনারি হিসাবে শ্রেণিবদ্ধ করার উপায় খুঁজছেন। কোনটি আরও কার্যকর: একটি "আমার স্ক্রিপ্ট ডিবাগ করুন" প্রশ্নটি ঘটে যা একটি জেনেরিক উত্তর অন্য স্ক্রিনের সাথে নির্দিষ্ট উত্তরগুলির মধ্যে সমাহিত হয়, বা একটি জেনেরিক "আমি কীভাবে ফিল্ডগুলিকে পাঠ্য বা বাইনারি হিসাবে শ্রেণিবদ্ধ করব?"
গিলস 21

1
@ গিলস - আপনি এটি কীভাবে পড়েন তার উপর নির্ভর করে। আমি সেখানে XY সমস্যার একটি সাধারণ ক্ষেত্রে হিসাবে প্রশ্নটি দেখতে পাই: ওপি সেখানে কোনও ফাইল কোনও টেক্সট ফাইল কিনা তা পরীক্ষা করতে চায় - এবং পাইপিংয়ের fileআউটপুটটি cutসমাধান বলে মনে করে - অবশ্যই, একটি অনুপস্থিত জায়গা রয়েছে যা এটি ব্যর্থ করে তোলে এবং এটি তৈরি করেছে বেশিরভাগ লোক X এর পরিবর্তে Y কে সম্বোধন করে তবে স্টাফেনের মন্তব্য এবং উত্তর ফাইলটি পাঠ্য কিনা তা নির্ধারণের সঠিক উপায় দেখায়।
don_crissti

উত্তর:


27

আপনি যদি fileকেবল মাইম-টাইপের জন্য জিজ্ঞাসা করেন তবে আপনি বিভিন্ন text/x-shellscriptএবং আরও অনেকগুলি পাবেন application/x-executableতবে আমি কল্পনা করি আপনি "টেক্সট" অংশটি পরীক্ষা করে দেখেন আপনার ভাল ফল পাওয়া উচিত। উদাহরণস্বরূপ ( -bআউটপুটে কোনও ফাইলের নাম নেই):

file -b --mime-type filename | sed 's|/.*||'

24
শুধু মনে রাখবেন, আপনার উপর নির্ভর করে file, আপনি কিছু টেক্সট ফরম্যাটের মিস্ পারে: application/xml(এবং আরএসএস মত অনুরূপ), application/ecmascript, application/json, image/svg+xml, ... আপনি কি পরিচ্ছন্ন তালিকাতে ঐ আছে চাই।
বোল্ডউইন

@ বোল্ডউইন বাহ, চমৎকার উদাহরণ! সুতরাং সম্ভবত আরও ভাল উত্তর হ'ল কেবল এমন মুদ্রণযোগ্য অক্ষর রয়েছে এমন কোনও ফাইল গ্রহণ করা, তবে কোনওভাবে utf-8 এবং অনুরূপ এনকোডিংয়ের সমস্যাগুলিও মোকাবেলা করা উচিত।
meuh

হ্যাঁ, এটি নীচে আমার উত্তরটির সংক্ষেপ। কেবল সমস্যাটি হ'ল, সেই সমাধানটির পুরো ফাইলটি দেখতে হবে ...
বোল্ডউইন

7
@ বোল্ডউইন নীতিগতভাবে, application/*প্রকারগুলি মানুষের ব্যবহারের উদ্দেশ্যে নয়, এমনকি যখন সেগুলি উন্নয়ন এবং ডিবাগিংয়ের সুবিধার্থে পাঠ্য-ভিত্তিক হতে পারে। এজন্য উভয়ই text/xmlএবং একটি আছে application/xml। সুতরাং প্রশ্নটি তাদের পাঠ্য হিসাবে বিবেচনা করবেন কিনা তা ওপরের প্রয়োজনের উপর নির্ভর করে।
টোবিয়া


20

আরেকটি পন্থা ব্যবহার করতে হবে isutf8থেকে moreutils সংগ্রহ।

ফাইলটি বৈধ ইউটিএফ -8 বা এএসসিআইআই, বা শর্ট সার্কিট, 0 এর সাথে প্রস্থান করে, একটি ত্রুটি বার্তা প্রিন্ট করে (সাথে নীরবতা দেয় -q) এবং অন্যথায় 1 দিয়ে প্রস্থান করে।


5
ভাল পরামর্শ। আমি কেবল লক্ষ্য করেছি যে একটি ডিরেক্টরিকে আরগ হিসাবে দেওয়ার ফলে এটি 0 ফিরে আসে I আমি কমপক্ষে 1 টি পছন্দ করতাম। তবে, আবর্জনা ভিতরে, আবর্জনা বাইরে।
meuh

13

আপনি যদি জিএনইউ দ্বারা ব্যবহৃত হিউরিস্টিক পছন্দ করেন তবে আপনি grepএটি ব্যবহার করতে পারেন:

isbinary() {
  LC_MESSAGES=C grep -Hm1 '^' < "${1-$REPLY}" | grep -q '^Binary'
}

এটি ফাইল থেকে পঠিত প্রথম বাফারে NUL বাইট অনুসন্ধান করে (নিয়মিত ফাইলের জন্য কয়েক কিলো-বাইট, তবে পাইপ বা সকেট বা কিছু ডিভাইসের জন্য অনেক কম হতে পারে /dev/random)। ইউটিএফ -8 লোকালে, এটি বাইট সিকোয়েন্সগুলিতে পতাকাও দেয় যা বৈধ UTF-8 অক্ষর তৈরি করে না। এটি ধরে নেওয়া LC_ALLহয় যে ভাষাটি ইংরেজি নয় এমন কোনও স্থানে সেট করা নেই।

${1-$REPLY}ফর্ম আপনি একটি হিসাবে এটি ব্যবহার করতে পারবেন zshউল্লিখিত glob কোয়ালিফায়ার:

ls -ld -- *(.+isbinary)

বাইনারি ফাইল তালিকাভুক্ত করা হবে ।


7

আপনি iconvফাইলটি পড়তে পারেন কিনা তা নির্ধারণের চেষ্টা করতে পারেন। এটি তুলনায় কম পারফরম্যান্স করছে file(যা শুরু থেকে কয়েকটা বাইট পড়ে) তবে আপনাকে আরও নির্ভরযোগ্য ফলাফল দেবে:

ENCODING=utf-8
if iconv --from-code="$ENCODING" --to-code="$ENCODING" your_file.ext > /dev/null 2>&1; then
    echo text
else
    echo binary
fi

এটি iconvমূলত কোনও অনিঃপত্তি তৈরি করে, তবে যদি এটি অবৈধ ডেটার মুখোমুখি হয় (এই উদাহরণে অবৈধ ইউটিএফ -8), তবে তা বারফ করে বেরিয়ে যাবে।


4
GNU দীর্ঘ বিকল্পগুলি ব্যবহার -fএবং -tপরিবর্তে এটি আরও বহনযোগ্য। মনে রাখবেন যে এটি যে ফাইলগুলিকে খুলতে পারে না তাকে "বাইনারি" বলবে। এটি খালি ফাইলগুলিকে "পাঠ্য" বলবে।
স্টাফেন চেজেলাস

একমত। আমি এডহক ডকুমেন্টেশনের জন্য দীর্ঘ ফর্মগুলি ব্যবহার করেছি, যারা জানেন না তাদের জন্য iconv। তবে -fএবং -tসাধারণত ভাল হয়।
বোল্ডউইন

7

আপনি কল করতে পারেন এমন কোনও স্ক্রিপ্ট লিখতে পারেন fileএবং আপনার আগ্রহী মামলাগুলি যাচাই করতে কেস-স্টেটমেন্ট ব্যবহার করতে পারেন।

উদাহরণ স্বরূপ

#!/bin/sh
case $(file "$1") in
(*script*|*\ text|*\ text\ *)
    echo text
    ;;
(*)
    echo binary
    ;;
esac

যদিও অবশ্যই অনেকগুলি বিশেষ মামলা হতে পারে যা আগ্রহী। কেবলমাত্র stringsএকটি অনুলিপি পরীক্ষা করে libmagicদেখছি, আমি প্রায় 200 টি মামলা দেখতে পাচ্ছি, যেমন,

Konqueror cookie text
Korn shell script text executable
LaTeX 2e document text
LaTeX document text
Linux Software Map entry text
Linux Software Map entry text (new format)
Linux kernel symbol map text
Lisp/Scheme program text
Lua script text executable
LyX document text
M3U playlist text
M4 macro processor script text

কেউ কেউ স্ট্রিংকে "টেক্সট" বিভিন্ন ধরণের অংশ হিসাবে ব্যবহার করে, যেমন,

SoftQuad troff Context intermediate   
SoftQuad troff Context intermediate for AT&T 495 laser printer
SoftQuad troff Context intermediate for HP LaserJet

একইভাবে scriptএকটি শব্দের অংশ হতে পারে, তবে আমি এই ক্ষেত্রে কোনও সমস্যা দেখছি না। তবে কোনও স্ক্রিপ্টের জন্য শব্দ"text" হিসাবে অনুসন্ধান করা উচিত , সাবস্ট্রিং নয়

অনুস্মারক হিসাবে, fileআউটপুট একটি সুনির্দিষ্ট বিবরণ ব্যবহার করে না যা সর্বদা "স্ক্রিপ্ট" বা "পাঠ্য" থাকবে। বিশেষ বিষয়গুলি বিবেচনা করার মতো বিষয়। একটি ফলোআপ মন্তব্য করেছে যে ফাইলগুলির --mime-typeজন্য এই পদ্ধতিটি কাজ করবে না .svg। তবে, একটি পরীক্ষায় আমি এই ফলাফলগুলি এসভিজি-ফাইলগুলির জন্য দেখতে পাই:

$ ls -l *.svg
-r--r--r-- 1 tom users  6679 Jul 26  2012 pumpkin_48x48.svg
-r--r--r-- 1 tom users 17372 Jul 30  2012 sink_48x48.svg
-r--r--r-- 1 tom users  5929 Jul 25  2012 vile_48x48.svg
-r--r--r-- 1 tom users  3553 Jul 28  2012 vile-mini.svg
$ file *.svg
pumpkin_48x48.svg: SVG Scalable Vector Graphics image
sink_48x48.svg:    SVG Scalable Vector Graphics image
vile-mini.svg:     SVG Scalable Vector Graphics image
vile_48x48.svg:    SVG Scalable Vector Graphics image
$ file --mime-type *.svg
pumpkin_48x48.svg: image/svg+xml
sink_48x48.svg:    image/svg+xml
vile-mini.svg:     image/svg+xml
vile_48x48.svg:    image/svg+xml

যা আমি বেছে নিয়েছি এমন এক হাজার ফাইল দেখার পরে মাইম-টাইপ আউটপুটটিতে "পাঠ্য" দিয়ে কেবল 6 টি প্রদর্শিত হয়। তর্কসাপেক্ষ, মাইম-টাইপ আউটপুট প্রান্তে "XML" মিলে আরো উপযোগী হতে পারে, ম্যাচিং "করা SVG" পরিবর্তে, বলে, কিন্তু একটি স্ক্রিপ্ট ব্যবহার করে না যে তুমি ফিরে লাগে পরামর্শ এখানে তৈরি।

আউটপুটটির জন্য fileউভয় দৃশ্যে কিছু টিউনিং প্রয়োজন, এবং এটি 100% নির্ভরযোগ্য নয় (এটি আমার পার্ল স্ক্রিপ্টগুলির বেশ কয়েকটি দ্বারা বিভ্রান্ত হয়ে তাদের "ডেটা" বলে ডাকে)।

এর একাধিক বাস্তবায়ন রয়েছে file। সর্বাধিক ব্যবহৃত এক এটির কাজ করে libmagicযা বিভিন্ন প্রোগ্রাম থেকে ব্যবহার করা যেতে পারে (সম্ভবত সরাসরি হতে পারে না zsh, যদিও pythonপারে)।

শেল, পার্ল, রুবি এবং পাইথনের ফাইল পরীক্ষার তুলনা সারণী অনুসারে পার্লের একটি -Tবিকল্প রয়েছে যা এটি এই তথ্য সরবরাহ করতে ব্যবহার করতে পারে। তবে এটি কোনও তুলনামূলক বৈশিষ্ট্য তালিকাভুক্ত করে না zsh

আরও পড়া:


দুর্ভাগ্যক্রমে fileএসএনজি ফাইলের জন্য জিএনইউ'র আউটপুট: SVG Scalable Vector Graphics imageপাঠ্য শব্দটি নেই। আমি ভেবেছিলাম মাইম-টাইপ যাচাইয়ের গ্রহণযোগ্য উত্তরের চেয়ে এই পদ্ধতিটি আরও ভাল হবে তবে এটি এখনও কিছু প্রকারের হাতছাড়া করে।
পিটার কর্ডেস

এটি এখনও মাইম-টাইপ সহ মিস করে; এক্সটার্মের এসভিজি ফাইলের জন্য আমি পাই image/svg+xml। প্রকৃতপক্ষে - কেবলমাত্র 1000-ফাইলের পরীক্ষা করা হয়েছে, কেবল মাইম-টাইপ অনুসারে 6 টি "পাঠ্য" হিসাবে প্রকাশিত হয়েছে। আমি একটি স্ক্রিপ্ট রেখেছি, যা কমপক্ষে প্রয়োজন মতো কাজ করা যায়।
টমাস ডিকি

3

fileএকটি বিকল্প রয়েছে --mime-encodingযা কোনও ফাইলের এনকোডিং সনাক্ত করার চেষ্টা করে।

 $file --mime-encoding Documents/poster2.pdf 
Documents/poster2.pdf: binary
 $file --mime-encoding projects/linux/history-torvalds/Makefile 
projects/linux/history-torvalds/Makefile: us-ascii
 $file --mime-encoding graphe.tex 
Dgraphe.tex: us-ascii
 $file --mime-encoding software.tex 
software.tex: utf-8

file --mime-encoding | grep binaryকোনও ফাইল বাইনারি ফাইল কিনা তা সনাক্ত করতে আপনি ব্যবহার করতে পারেন। এটি নির্ভরযোগ্যভাবে কাজ করে যদিও এটি দীর্ঘ পাঠ্য ফাইলে একটি একক অবৈধ অক্ষর দ্বারা বিভ্রান্ত হতে পারে।

উদাহরণস্বরূপ, catঅজান্তে একটি বাইনারি ফাইল খোলার মাধ্যমে আমার টার্মিনালটি নষ্ট করা এড়াতে আমি নিম্নলিখিত শেল স্ক্রিপ্টে উপন্যাস রেখেছি:

#! /bin/sh -

[ ! -t 1 ] && exec /bin/cat "$@"
for i
do
    if file --mime-encoding -- "$i" | grep -q binary
    then
        hexdump -C -- "$i"
    else
        /bin/cat -- "$i"
    fi
done

3

বিভাগগুলি নির্বিচারে হয়। শ্রেণিবদ্ধকরণ কীভাবে করবেন তার উত্তর দেওয়ার আগে আপনার (কঠোর) সংজ্ঞা দরকার। সংজ্ঞা রাখতে গেলে আপনার একটি উদ্দেশ্য প্রয়োজন

সুতরাং, আপনি এই শ্রেণিবদ্ধকরণটি দিয়ে কী করতে চান?

  • আপনি যদি এফটিপিতে ascii / বাইনারি নির্বাচন করতে চান তবে এটি গুরুত্বপূর্ণ যে কোনও বাইনারি ফাইল ascii হিসাবে স্থানান্তর করবেন না (অথবা এটি দূষিত হবে)। সুতরাং আপনি যদি ফাইলটি সরল পাঠ, এইচটিএমএল, আরটিএফ এবং অন্য কিছু হয় তবে পরীক্ষা করতে হবে। তবে সন্দেহ, বাইনারি নির্বাচন করুন। এবং আপনি এটিও পরীক্ষা করতে চান যে ফাইলটিতে কেবল 0x0A, 0x0D, এবং 0x20-0x7F এর মতো একটি উপসেট রয়েছে।
  • আপনি যদি কিছু প্রোটোকল (পিওপি 3, এসএমটিপি) ফাইলটি স্থানান্তর করতে চান তবে বেস 64 বা কেবল সরল ক্ষেত্রে এনকোড রয়েছে কিনা তা পরীক্ষা করতে আপনাকে পরীক্ষা করতে হবে। এই ক্ষেত্রে, অসমর্থিত অক্ষর আছে কিনা তা পরীক্ষা করা উচিত।
  • অন্য কোনও ক্ষেত্রে… এর অন্য কোনও সংজ্ঞা থাকতে পারে।

3
perl -e'chomp(my$f=<>);print "binary$/" if -B $f;print "text$/" if -T _'

এটা করবো. এর জন্য ডকুমেন্টেশন-B-T দেখুন এবং (স্ট্রিংয়ের জন্য পৃষ্ঠাটিতে সন্ধান করুন The -T and -B switches work as follows)।


perl -le 'print -B $ARGV[0] ? "binary" : "text"' --পরিষ্কার হতে পারে। বা এমনকিperl -le 'print -B $_ ? "binary" : "text", @ARGV > 1 ? "\t$_" : "" for @ARGV' --
jrw32982 মনিকা

1

আমি https://github.com/audreyr/binaryornot এ অবদান রেখেছি এটিতে একটি কমান্ড লাইন মোড়ক নেই (এখনও) তবে এটি একটি সাধারণ পাইথন লাইব্রেরি এমনকি সিএলআই থেকে কল করা যথেষ্ট সহজ। কোনও ফাইল পাঠ্য বা বাইনারি কিনা তা নির্ধারণ করতে এটি মোটামুটি দক্ষ হিউরিস্টিক ব্যবহার করে।


1

আমি এখন এই উত্তরটি কিছুটা পুরানো, তবে আমার কাছে মনে হয় আমার বন্ধু আমাকে এটি করতে একটি দুর্দান্ত "হ্যাক" শিখিয়েছে।

আপনি diffআদেশটি ব্যবহার করেন এবং পরীক্ষার পাঠ্য ফাইলের বিরুদ্ধে আপনার ফাইলটি পরীক্ষা করে দেখুন:

$ diff filetocheck testfile.txt

এখন যদি filetocheckবাইনারি ফাইল হয় তবে আউটপুটটি হবে:

Binary files filetocheck and testfile.txt differ

আপনি diffকমান্ডটি উত্তোলন করতে পারেন এবং উদাহরণস্বরূপ একটি ফাংশন লিখুন যা স্ক্রিপ্টে চেক করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.