इसे चलाने के लिए सबसे सरल और सबसे पोर्टेबल उत्तर है:
#!/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
फ़िल्टरेस्ट ऑपरेटर का समर्थन करता है , और न ही यह एन्कोडिंग को पहचानता है यदि ऐसा किया है - जिसे आपको UTF-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
और अगर आप चाहते हैं कि पर्ल को इसकी फाइलें UTF-8 में हों, तो उपयोग करें
$ find2perl * -type T -exec sed 's/[ \t]*$//' -i {} \; | perl -CSD
या आप परिणामी स्क्रिप्ट को किसी फ़ाइल में सहेज सकते हैं और उसे संपादित कर सकते हैं। आपको वास्तव में -T
किसी भी पुरानी फाइल पर सिर्फ फिलैट नहीं चलाना चाहिए , बल्कि केवल उन फाइलों पर होना चाहिए जो पहले से निर्धारित की गई हैं -f
। अन्यथा आप डिवाइस खोलने का जोखिम उठाते हैं, पंद्रह को रोकते हैं, आदि।
हालाँकि, यदि आप वह सब करने जा रहे हैं, तो आप पूरी तरह से sed (1) छोड़ सकते हैं। एक बात के लिए, यह अधिक पोर्टेबल है, क्योंकि POSIX संस्करण सेड (1) समझ में नहीं आता है -i
, जबकि पर्ल के सभी संस्करण करते हैं। की Latterday संस्करणों sed प्यार से बहुत उपयोगी विनियोजित -i
पर्ल जहां ti पहले प्रकट होता है से विकल्प।
यह आपको अपने रेगेक्स को ठीक करने का अवसर भी देता है। आपको वास्तव में एक पैटर्न का उपयोग करना चाहिए जो एक या अधिक अनुलंब क्षैतिज व्हाट्सएप से मेल खाता है, न केवल उनमें से शून्य, या आप अनावश्यक नकल से धीमी गति से चलेंगे। वह यह है:
s/[ \t]*$//
होना चाहिए
s/[ \t]+$//
हालांकि, यह समझने के लिए कि कैसे एक गैर-पॉसिक्स एक्सटेंशन की आवश्यकता होती है , सीड (1) प्राप्त करें, आमतौर पर या तो -R
सिस्टम के लिए होता है जैसे सोलारिस या लिनक्स, या -E
ओपनबीएसडी या मैकओएस जैसे बीएसडी वाले। मुझे संदेह है कि यह AIX के तहत असंभव है। पोर्टेबल शेल स्क्रिप्ट की तुलना में पोर्टेबल शेल लिखना आसान है, आप जानते हैं।
0xA0 पर चेतावनी
हालांकि वे ASCII में केवल क्षैतिज सफेद अंतरिक्ष वर्ण हैं, दोनों ISO-8859-1 और परिणामस्वरूप यूनिकोड में कोड बिंदु U + 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
प्रत्येक लाइन के अंत में यूनिकोड लाइनब्रेक (CRLF कॉम्ब्स शामिल करें) से पहले pesky NO-BREAK स्पेस सहित क्षैतिज व्हाट्सएप (यूनिकोड कैरेक्टर प्रॉपर्टी ) को हटाने से छुटकारा न मिले ।
यह sed (1) संस्करण की तुलना में बहुत अधिक पोर्टेबल है , क्योंकि केवल एक पर्ल (1) कार्यान्वयन है, लेकिन कई sed (1)।
मुख्य समस्या जो मुझे दिखाई देती है, वह ढूंढने (1) के साथ है, क्योंकि कुछ सचमुच पुनर्गणना प्रणालियों पर (आप जानते हैं कि आप कौन हैं, AIX और सोलारिस), यह सुपरक्रिटिकल -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;
यदि आप ASCII या ISO-8859-1 टेक्स्टफाइल्स पर चल रहे हैं, तो यह ठीक है, लेकिन यदि आप ASCII या UTF-8 फ़ाइलों के साथ चल रहे हैं, -CSD
तो आंतरिक कॉल में स्विच को पर्ल में जोड़ें।
यदि आपके पास ASCII, ISO-8859-1, और UTF-8, तीनों के मिश्रित एनकोडिंग हैं, तो मुझे डर है कि आपको एक और समस्या है। :( आपको प्रति-फ़ाइल के आधार पर एन्कोडिंग का पता लगाना होगा, और ऐसा अनुमान लगाने का एक अच्छा तरीका नहीं है।
यूनिकोड व्हाट्सएप
रिकॉर्ड के लिए, यूनिकोड में 26 अलग-अलग व्हाट्सएप चरित्र हैं। आप इन को सूँघने के लिए यूनीचर्स यूटिलिटी का उपयोग कर सकते हैं । केवल पहले तीन क्षैतिज व्हाट्सएप चार्ट लगभग कभी देखे गए हैं:
$ 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