আমি কীভাবে এই `Find` কমান্ডটি চালাব, তবে কেবল নন-বাইনারি ফাইলগুলিতে?


8

আমি একটি পুনরাবৃত্ত ডিরেক্টরি ডিরেক্টরি শ্রেণিবিন্যাসের সমস্ত ফাইল থেকে ট্রেলিং হোয়াইটস্পেসটি সরাতে চাই। আমি এটি ব্যবহার:

find * -type f -exec sed 's/[ \t]*$//' -i {} \;

এটি কাজ করে, তবে পাওয়া যায় এমন বাইনারি ফাইলগুলি থেকে "হোয়াইটস্পেস" অনুসরণ করবে, যা অনাকাঙ্ক্ষিত।

findবাইনারি ফাইলগুলিতে এই কমান্ডটি চালনা এড়াতে আমি কীভাবে বলব ?


ইউনিক্স ফাইল সিস্টেমগুলি "বাইনারি" এবং "নন-বাইনারি" ফাইলগুলির মধ্যে কোনও পার্থক্য করে না; ফাইলের মধ্যে কী ধরণের ডেটা রয়েছে তা না বলার উপায় নেই।
ওবল ২

@ উবল: এটি সঠিক, তবে এমন কমান্ড রয়েছে fileযা ডেটা পরীক্ষা করতে পারে।
জন ফেমেনেলা

উত্তর:


4

আপনি fileচাইছেন না এমন ফাইলগুলি সনাক্ত করতে আপনি ইউনিক্স কমান্ডটি ব্যবহার করার চেষ্টা করতে পারেন, তবে আমি মনে করি যে আপনি যা না চান তার চেয়ে আপনি কোন ফাইল হিট করতে চান তা স্পষ্ট করে নির্দিষ্ট করে দেওয়া ভাল।

find * -type f \( -name \*.java -o -name \*.c -o -name \*.sql \) -exec sed 's/[ \t]*$//' -i {} \;

উত্স নিয়ন্ত্রণ ফাইলগুলিতে প্রবেশ করা এড়াতে আপনার মতো কিছু হতে পারে

find * \! \( -name .svn -prune \) -type f \( -name \*.java -o -name \*.c -o -name \*.sql \) -exec sed 's/[ \t]*$//' -i {} \;

আপনার শেলের উপর নির্ভর করে আপনার কিছু ব্যাকস্ল্যাশ প্রয়োজন হতে পারে বা নাও পারে।


2
আমি আপনার সম্পর্কে জানি না, তবে আমাদের সমস্ত জাভা উত্স ফাইলগুলি সর্বদা স্ট্যান্ডার্ড ইউটিএফ -8 এ থাকে, যাতে সেড কমান্ড সর্বদা সেই সবগুলির সাথে সঠিক কাজটি করে না। আমার কাছে সিড-i করার বিকল্প ছাড়াও সিস্টেম রয়েছে । পোর্টেবল শেল কমান্ড লেখা শক্ত, তাই না?
tchrist

4

এটি কমান্ড লাইনে করা যেতে পারে।

$ find . -type f -print|xargs file|grep ASCII|cut -d: -f1|xargs sed 's/[ \t]*$//' -i

3

সবচেয়ে সহজ এবং বহনযোগ্য উত্তর হ'ল এটি চালানো:

#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
my @dirs = (@ARGV == 0) ? <*> : @ARGV;
find sub {
    next unless -f && -T;
    system('perl', '-i', '-pe', 's/[\t\xA0 ]+$//', $File::Find::name);
} => @dirs;

আমি নীচে কেন তা ব্যাখ্যা করেছি, যেখানে আমি কেবল কমান্ড লাইনটি ব্যবহার করে এটি কীভাবে করব এবং পাশাপাশি আইএসও -8859-1 (ল্যাটিন -1) এবং ইউটিএফ -8 এর মতো ট্রান্স-এএসসিআইআই পাঠ্য ফাইলগুলি কীভাবে মোকাবেলা করতে হবে তাও ব্যাখ্যা করি তাদের মধ্যে এএসসিআইআই হোয়াইটস্পেস।


গল্প বাকি

সমস্যাটি হ'ল সন্ধান করুন (1) -Tফাইলস্টেস্ট অপারেটরকে সমর্থন করে না , বা এটি যদি এনকোডিংগুলি সনাক্ত করে তবে তা সনাক্ত করে না - যা আপনাকে একেবারে ইউটিএফ -8 সনাক্ত করতে হবে, ইউনিকোডের সত্যিকারের স্ট্যান্ডার্ড।

আপনি যা করতে পারতেন তা হল ফাইলের নাম তালিকাটি এমন একটি স্তরের মাধ্যমে চালিত যা বাইনারি ফাইলগুলি ছুঁড়ে দেয়। উদাহরণ স্বরূপ

$ find . -type f | perl -nle 'print if -T' | xargs sed -i 's/[ \t]*$//'

তবে এখন আপনার ফাইলের নামগুলিতে হোয়াইটস্পেস নিয়ে আপনার সমস্যা আছে, তাই আপনাকে নাল সমাপ্তির সাথে বিলম্ব করতে হবে:

$ find . -type f -print0 | perl -0 -nle 'print if -T' | xargs -0 sed -i 's/[ \t]*$//'

আরেকটা জিনিস আপনি করতে পারতেন ব্যবহার না findকিন্তু find2perl, যেহেতু পার্ল বুঝতে পারে -Tইতিমধ্যে:

$ find2perl * -type T -exec sed 's/[ \t]*$//' -i {} \; | perl

এবং আপনি যদি পার্ল ধরে নিতে চান যে এর ফাইলগুলি ইউটিএফ -8 এ রয়েছে, ব্যবহার করুন

$ find2perl * -type T -exec sed 's/[ \t]*$//' -i {} \; | perl -CSD

অথবা আপনি ফলস্বরূপ স্ক্রিপ্টটি কোনও ফাইলে সংরক্ষণ করতে এবং সম্পাদনা করতে পারেন। আপনি সত্যিই সত্যিই শুধু চালানো উচিত -Tকোন পুরাতন ফাইলের উপর filetest, বরং তারা শুধু সেই সব প্লেইন ফাইল হিসাবে প্রথম কর্তৃক নির্ধারিত উপর -f। অন্যথায় আপনি ডিভাইস বিশেষ খোলার, ফিফোসকে ব্লক করা ইত্যাদি ঝুঁকিপূর্ণ করেন

যাইহোক, যদি আপনি যে সব কি করতে যাচ্ছি, আপনি হিসাবে ভাল কর পারে sed (1) পুরাপুরি। একটি জিনিস হিসাবে, এটি আরও বহনযোগ্য, যেহেতু সেড (1) এর পসিক্স সংস্করণ বুঝতে পারে না -i, যেখানে পার্লের সমস্ত সংস্করণ রয়েছে। এর Latterday সংস্করণ sed প্রেমের সঙ্গে খুব দরকারী appropriated -iপার্ল যেখানে TI প্রথম প্রদর্শিত হয় সেখান থেকে বিকল্প।

এটি আপনাকে আপনার রেজেক্সও ঠিক করার সুযোগ দেয়। আপনার সত্যিকারের এমন একটি প্যাটার্ন ব্যবহার করা উচিত যা এক বা একাধিক অনুভূমিক শ্বেতস্পেসের সাথে মেলে, কেবল তার শূন্য নয়, বা আপনি অপ্রয়োজনীয় অনুলিপি থেকে ধীরে ধীরে চলবেন। এটি, এটি:

 s/[ \t]*$//

হতে হবে

 s/[ \t]+$//

যাইহোক, পেতে কিভাবে sed (1) বুঝতে পেরেছিল যে একটি অ-POSIX এক্সটেনশন, সাধারণত হয় প্রয়োজন -Rসোলারিস অথবা Linux বা এগুলির মতো সিস্টেম Ⅴ Unices জন্য -EOpenBSD বা MacOS এর মত বাসদ বেশী জন্য। আমার সন্দেহ হয় এআইএক্স এর অধীনে এটি অসম্ভব। পোর্টেবল শেল স্ক্রিপ্টের চেয়ে পোর্টেবল শেলটি লিখতে পাত্তাই হ'ল আপনারা জানেন।

0xA0 এ সতর্কতা

যদিও এএসসিআইআই-তে কেবলমাত্র অনুভূমিক সাদা স্থানের অক্ষর, তবে আইএসও -8859-1 এবং ফলস্বরূপ ইউনিকোডের কোড পয়েন্ট ইউ + 00A0-তে NO-BREAK স্পেস রয়েছে। অনেক ইউনিকোড কর্পোরায় এটি পাওয়া শীর্ষ দুটি নন-এএসসিআইআই চরিত্রগুলির মধ্যে একটি এবং আমি ইদানীং প্রচুর লোকের রেজেক্স কোড ব্রেক দেখেছি কারণ তারা এটিকে ভুলে গিয়েছিল।

সুতরাং আপনি কেবল এটি করবেন না কেন:

$ find * -print0 | perl -0 -nle 'print if -f && -T' | xargs -0 perl -i -pe 's/[\t\xA0 ]+$//'

আপনি হল UTF-8 সঙ্গে, অ্যাড মোকাবেলা করতে ফাইল থাকতে পারে তাহলে -CSD, এবং আপনি পার্ল v5.10 বা তার অধিক চালান তাহলে আপনি ব্যবহার করতে পারেন \hঅনুভূমিক হোয়াইটস্পেস এবং \Rএকটি জেনেরিক LINEBREAK, যার মধ্যে জন্য \r, \n, \r\n, \f, \cK, \x{2028}, এবং \x{2029}:

$ find * -print0 | perl -0 -nle 'print if -f && -T' | xargs -0 perl -CSD -i -pe 's/\h+(?=\R*$)//'

এটি সমস্ত ইউটিএফ -8 ফাইলগুলিতে তাদের লাইনব্রেকগুলি বিবেচনা HorizSpaceনা করেই কাজ করবে, প্রতিটি লাইনের শেষে ইউনিকোড লাইনব্রেকের আগে ঘটে যাওয়া (সিআরএলএফ কম্বোস অন্তর্ভুক্ত) পেসকি নো-BREAK স্পেস সহ পেজ অনুভূমিক সাদা স্থান (ইউনিকোড চরিত্রের সম্পত্তি ) থেকে মুক্তি পেয়ে ।

এটি সেড (1) সংস্করণের চেয়েও অনেক বেশি বহনযোগ্য , কারণ কেবলমাত্র একটি পার্ল (1) বাস্তবায়ন রয়েছে তবে অনেকগুলি সেড (1) রয়েছে।

প্রধান সমস্যা আমি সেখানে থাকতে দেখবে সাথে আছেন খোঁজ যেহেতু কিছু সত্যিই অবাধ্য সিস্টেমে (আপনি জানি আপনি কে,, AIX এবং সোলারিস), (1), এটা supercritical বুঝবে না -print0ডিরেক্টিভের। যদি এটি আপনার পরিস্থিতি হয় তবে আপনার অবশ্যই File::Findপার্ল থেকে সরাসরি মডিউলটি সরাসরি ব্যবহার করা উচিত এবং অন্য কোনও ইউনিক্স ইউটিলিটি ব্যবহার করা উচিত নয়। এখানে আপনার কোডের খাঁটি পার্ল সংস্করণ যা অন্য কোনও কিছুর উপর নির্ভর করে না:

#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
my @dirs = (@ARGV == 0) ? <*> : @ARGV;
find sub {
     next unless -f && -T;
     system('perl', '-i', '-pe', 's/[\t\xA0 ]+$//', $File::Find::name);  
} => @dirs;

আপনি যদি কেবল এএসসিআইআই বা আইএসও -8859-1 টেক্সটফাইলে চালিয়ে যাচ্ছেন তবে তা ঠিক আছে তবে আপনি যদি এসসিআইআই বা ইউটিএফ -8 ফাইলের সাথে চলতে -CSDথাকেন তবে পার্লের অভ্যন্তরীণ কলটিতে স্যুইচগুলি যুক্ত করুন ।

আপনার যদি এএসসিআইআই, আইএসও -8859-1 এবং ইউটিএফ -8 তিনটির মিশ্র এনকোডিং থাকে তবে আমি আশঙ্কা করি যে আপনার আর একটি সমস্যা আছে। :( আপনাকে প্রতি ফাইলের ভিত্তিতে এনকোডিংটি বের করতে হবে এবং এটি অনুমান করার ভাল উপায় আর কখনও নেই।

ইউনিকোড হোয়াইটস্পেস

রেকর্ডের জন্য, ইউনিকোডে 26 টি পৃথক সাদা স্থান রয়েছে। আপনি ব্যবহার করতে পারেন unichars ইউটিলিটি এই আউট শোঁকা করতে। কেবলমাত্র প্রথম তিনটি অনুভূমিক সাদা স্থানগুলি প্রায় সর্বদা দেখা যায়:

$ unichars '\h'
 ---- U+0009 CHARACTER TABULATION
 ---- U+0020 SPACE
 ---- U+00A0 NO-BREAK SPACE
 ---- U+1680 OGHAM SPACE MARK
 ---- U+180E MONGOLIAN VOWEL SEPARATOR
 ---- U+2000 EN QUAD
 ---- U+2001 EM QUAD
 ---- U+2002 EN SPACE
 ---- U+2003 EM SPACE
 ---- U+2004 THREE-PER-EM SPACE
 ---- U+2005 FOUR-PER-EM SPACE
 ---- U+2006 SIX-PER-EM SPACE
 ---- U+2007 FIGURE SPACE
 ---- U+2008 PUNCTUATION SPACE
 ---- U+2009 THIN SPACE
 ---- U+200A HAIR SPACE
 ---- U+202F NARROW NO-BREAK SPACE
 ---- U+205F MEDIUM MATHEMATICAL SPACE
 ---- U+3000 IDEOGRAPHIC SPACE

$ unichars '\v'
 ---- U+000A LINE FEED (LF)
 ---- U+000B LINE TABULATION
 ---- U+000C FORM FEED (FF)
 ---- U+000D CARRIAGE RETURN (CR)
 ---- U+0085 NEXT LINE (NEL)
 ---- U+2028 LINE SEPARATOR
 ---- U+2029 PARAGRAPH SEPARATOR

0

কোনও ফাইল বাইনারি কিনা তা সনাক্ত করতে জিএনইউ গ্রেপ বেশ ভাল। সোলারিস ব্যতীত আমি নিশ্চিত যে অন্যান্য প্ল্যাটফর্মগুলি জিএনইউ গ্রেপের সাথে ডিফল্টরূপে ইনস্টল হয় না তবে সোলারিসের মতো আমিও নিশ্চিত যে আপনি এটি ইনস্টল করতে পারবেন।

perl -pi -e 's{[ \t]+$}{}g' `grep -lRIP '[ \t]+$' .`

আপনি যদি সোলারিসে থাকেন তবে আপনি এটি প্রতিস্থাপন grepকরবেন /opt/csw/bin/ggrep

grepপতাকা নিচের কাজগুলো করুন: l, ম্যাচিং ফাইলের জন্য শুধুমাত্র তালিকা ফাইলের নামের Rরিকার্সিভ হয়, I(বাইনারি ফাইল উপেক্ষা করে) শুধুমাত্র পাঠ্য ফাইল মিলে যায়, এবং PPerl সামঞ্জস্যপূর্ণ রেগুলার এক্সপ্রেশন সিনট্যাক্স জন্য।

পার্ল অংশটি স্থানের মধ্যে স্থানটি পরিবর্তন করে, সমস্ত অনুসরণকারী স্থান / ট্যাব মোছা।

শেষ অবধি: যদি ইউটিএফ 8 কোনও সমস্যা হয় তবে আমার সাথে মিলিত ট্রাইস্ট্রিস্টের উত্তর যথেষ্ট হওয়া উচিত, যদি আপনার তৈরিটি grepইউটিএফ 8 সমর্থন দিয়ে নির্মিত হয় (সাধারণত প্যাকেজ রক্ষণাবেক্ষণকারীরা এই ধরণের কার্যকারিতা সরবরাহ করার চেষ্টা করেন)।

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