সবচেয়ে সহজ এবং বহনযোগ্য উত্তর হ'ল এটি চালানো:
#!/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 জন্য -E
OpenBSD বা 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