मैं ऐसी फ़ाइल को कैसे हटा सकता हूं जिसमें फ़ाइल नाम में गैर-मुद्रण वर्ण हैं


46

मैं किसी तरह एक फ़ाइल बनाने में कामयाब रहा, जिसमें फ़ाइल नाम नहीं है। मुझे निम्नलिखित थ्रेड में फ़ाइल के अधिक विवरण कैसे प्राप्त करने के बारे में कुछ जानकारी मिली

हालाँकि, मैंने सूचीबद्ध कुछ सुझावों की कोशिश की और फ़ाइल को हटाने के लिए प्रतीत नहीं हो सकता है। मुझे यकीन नहीं है कि मैंने इसे बनाने के लिए क्या किया था, लेकिन यह एक xml फ़ाइल को कॉपी करने की कोशिश करते समय हुआ।

फ़ाइल की कुछ जानकारी इस प्रकार है;

> ls -lb
total 296
-rw-r--r--   1 voyager  endeavor  137627 Jan 12 12:49 \177

> file *
:               XML document

> ls -i
 417777   

मैंने इनम स्विच का उपयोग करके खोजने की कोशिश की और फिर उस पाइप को आरएम करने के लिए जैसे कि इसे निकालने का सबसे मूर्खतापूर्ण तरीका लग रहा था। हालाँकि, नीचे दिए गए धागे के नीचे दिया गया उदाहरण मेरे लिए विफल रहा। उदाहरण था:

> find -inum 41777 -exec ls -al {} \;
find: illegal option -- i
find: [-H | -L] path-list predicate-list

इसलिए मैंने पहले की तरह पथ सूची का उपयोग करने की कोशिश की, लेकिन यह भी काम नहीं किया:

> find . -inum 41777 -exec ls -al {} \;

मुझे यकीन नहीं है कि गैर-मुद्रण योग्य वर्ण \ 177 क्या है या मैं इसे एक rmकमांड में कैसे पारित कर सकता हूं , लेकिन मैं वास्तव में यह सुनिश्चित करना चाहता हूं कि मैं इस फाइल को हटाने के अपने प्रयास में किसी अन्य फाइल / निर्देशिका को गड़बड़ न करूं।


1
\177ASCII DELवर्ण है।
कीथ थॉम्पसन

9
417777! = 41777
एक CVn

उत्कृष्ट बिंदु माइकल। शायद इसीलिए मेरी आज्ञा ने कभी काम नहीं किया।
श्री मूज़

@KeithThompson क्या यह एक प्रमुख के बिना अष्टक है 0?
बिल्ली

1
@ कोट: इस संदर्भ में, हाँ। यह स्ट्रिंग और वर्ण शाब्दिकों के लिए C सिंटैक्स का अनुसरण करता है।
कीथ थॉम्पसन

जवाबों:


46

फ़ाइल का एक नाम है, लेकिन यह गैर-मुद्रण योग्य वर्णों से बना है। यदि आप ksh93, bash, zsh, mksh या FreeBSD sh का उपयोग करते हैं, तो आप इसके गैर-मुद्रण योग्य नाम को निर्दिष्ट करके इसे हटाने का प्रयास कर सकते हैं। पहले यह सुनिश्चित करें कि नाम सही है: ls -ld $'\177' यदि यह सही फ़ाइल दिखाता है, तो rm का उपयोग करें:rm $'\177'

एक और (थोड़ा और अधिक जोखिम भरा) दृष्टिकोण का उपयोग करना है rm -i -- *। -I विकल्प आरएम के साथ एक फाइल को हटाने से पहले पुष्टि की आवश्यकता होती है, इसलिए आप उन सभी फाइलों को छोड़ सकते हैं जिन्हें आप रखना चाहते हैं लेकिन एक।

सौभाग्य!


1
मुझे संदेह है कि rm -i *इस मामले में काम नहीं किया होगा; newlines के कारण, शेल *कुछ ऐसे चीज़ों तक विस्तारित rmहोगा जो फ़ाइल नाम के रूप में नहीं पहचाने जाएंगे।
कीथ थॉम्पसन

6
@KeithThompson: शेल में ग्लोब विस्तार आगे व्याख्या के अधीन नहीं है। जब तक इसमें एक भी शामिल नहीं होता तब तक विस्तारित नाम में एक नई रूपरेखा नहीं होगी।
क्रिस्टोफर हैमरस्ट्रॉम

@ क्रिस्टोफ़रहम्मरस्ट्रम: हम्म। मैं कुछ प्रयोग करूंगा और आगे टिप्पणी करूंगा।
कीथ थॉम्पसन

@ ChristofferHammarström: विस्तारित नाम में एक नई रेखा है क्योंकि फ़ाइल नाम में नई वर्ण हैं। लेकिन ऐसा लगता है कि मैंने कम bashऔर जीएनयू को कम करके आंका है rm। अपने सिस्टम पर, rm *, rm -i *, और rm Ctrl-V DEL TAB ENTERसब काम सही ढंग से, फ़ाइल नाम एक नई पंक्ति चरित्र (मैं का इस्तेमाल किया होता है, भले ही "\177foo\nbar\n")। कुछ कमांड ऐसे फ़ाइल नामों को अच्छी तरह से संभाल नहीं पाते हैं, लेकिन GNU टूल मजबूत लगते हैं; एक ही उपकरण के गैर-जीएनयू संस्करण भी व्यवहार नहीं कर सकते हैं। किसी भी मामले में, इन उत्तरों में विभिन्न चालें जानना उपयोगी है।
कीथ थॉम्पसन

1
@KeithThompson, कोई भी शेल सही ढंग से फ़ाइल ग्लोबिंग को हैंडल करेगा, न केवल बैश, और rmकभी भी शब्द के किसी भी रूप को विभाजित नहीं करता है कि यह GNU है rmया नहीं। शेल ग्लब्स का विस्तार करता है और, जब यह कमांड कमांड को निष्पादित करता है, तो यह परिणामी फ़ाइलनामों में अशक्त अलग तर्क (सी कोड में) के रूप में गुजरता है। खतरनाक चीज़ों की एक सूची को पाइप करने के लिए क्या खतरनाक है, जो नए सिरे से सीमांकक का उपयोग करता है ; देखें कि लूपिंग आउटपुट की खराब प्रथा के कारण क्यों लुप्त होती है?
वाइल्डकार्ड

23

उन लोगों के लिए जो इसका उपयोग vimवर्तमान कार्य निर्देशिका में करते हैं:

$ vim ./ 

और तीर कुंजियों के साथ फ़ाइल में नेविगेट करें या j/k। फिर हिट करें Shift+Dऔर हटाने की पुष्टि करें y


मैं आमतौर पर विम से डर जाता हूं, लेकिन यह वास्तव में अच्छी तरह से काम करता है
टॉफुटिम

9

शायद फ़ाइलनाम को पास करने का एक तरीका है rm, लेकिन अगर आप किसी चीज़ को गड़बड़ करने के बारे में चिंतित हैं तो आप GUI फ़ाइल प्रबंधक का उपयोग कर सकते हैं। Emacs एक निर्देशिका संपादन मोड के साथ आता है जिसे आप इसे स्थापित करने पर उपयोग कर सकते हैं:

  1. में फ़ोल्डर खोलें emacs। आप दौड़ सकते हैं emacs /path/to/folder, या emacs खोल सकते हैं , हिट Esc+ xऔर चला सकते हैं dired, जो पथ के लिए संकेत देगा

    http://so.mrozekma.com/unix-dired-delete1.png

  2. उस फ़ाइल के साथ पंक्ति पर जाएं जिसे आप हटाना चाहते हैं और दबाएं d। आपको Dफ़ाइल के बगल में बाएं मार्जिन में एक देखना चाहिए :

    http://so.mrozekma.com/unix-dired-delete2.png

  3. xअपने परिवर्तनों को सहेजने के लिए दबाएं । यह सुनिश्चित करने के लिए संकेत देगा कि आप फ़ाइल को हटाना चाहते हैं; प्रेस y:

    http://so.mrozekma.com/unix-dired-delete3.png


1
एक महान विचार की तरह लग रहा है, लेकिन मैं इस मशीन पर emacs खोजने के लिए प्रतीत नहीं कर सकते। पवित्र युद्ध शुरू करने के जोखिम पर ... क्या यह व्यर्थ हो सकता है?
श्री मूस

2
उन लोगों के लिए जो vimइसे वर्तमान कार्य निर्देशिका में चलाते हैं: vim ./और तीर कुंजियों के साथ फ़ाइल पर नेविगेट करें। फिर हिट करें Shift+Dऔर हटाने की पुष्टि करें y

@ ह्से वाह। कुछ नहीं मैं उम्मीद कर लिया जाएगा vimसमर्थन करने के लिए
माइकल Mrozek

1
@MichaelMrozek ने सहमति व्यक्त की, इसमें ये सभी विशेषताएं हैं जिन्हें मैं जानबूझकर खोजता हूं।

1
@ केविन न्यान मोड: nyan-mode.buildsomethingamazing.com
टिम

8

आपने पहले ही प्रदर्शित कर दिया है file *कि शेल ग्लोब ( *) इस फ़ाइल को लेने में सक्षम है, इसलिए अब बस rmउस ग्लोब पर एक कार्य करें ।

  • फ़ाइल जिस निर्देशिका में है उसे बदलें।
  • Daud rm -i *
  • nप्रतीत होता है अदृश्य फ़ाइल नाम के साथ एक को छोड़कर सभी फ़ाइलों के लिए दर्ज करें

7

फ़ाइल में वास्तव में एक नाम है, लेकिन यह गैर-मुद्रण योग्य वर्णों से बना है।

एक आसान तरीका शेल पूरा होने पर भरोसा करना है: Tab"अजीब" फ़ाइल नाम डालने तक बार-बार दबाएं । संभव पूर्णताओं के बीच आपको अपने शेल को चक्र में कॉन्फ़िगर करना होगा:

  • बैश में, आपको आह्वान करने की आवश्यकता है menu-complete, जो डिफ़ॉल्ट रूप से बाध्य नहीं है, बल्कि डिफ़ॉल्ट रूप से completeबाध्य है Tab। वैकल्पिक रूप से, Esc *सभी फ़ाइलों के लिए पूर्णताएँ सम्मिलित करने के लिए उपयोग करें, और जिन्हें आप कमांड लाइन से हटाना नहीं चाहते हैं उन्हें हटा दें।
  • Zsh में, डिफ़ॉल्ट सेटिंग्स ठीक हैं; आपके पास होना चाहिए setopt auto_menuया setopt menu_completeसेट होना चाहिए।

यदि पूर्णता आपके शेल में सहायक नहीं है, तो आप rm -i -- *इस विशेष फ़ाइल को छोड़कर "नहीं" कॉल कर सकते हैं और उत्तर दे सकते हैं । यदि फ़ाइल का नाम मुद्रण योग्य वर्ण से शुरू नहीं होता है, तो आप उन मेलों को उन फ़ाइलों तक सीमित कर सकते हैं जिनका पहला वर्ण मुद्रण योग्य वर्ण के सेट में नहीं है:

rm -i [!!-~]*
rm -i [![:print:]]*
rm -i -- [!a-z]

(खबरदार अगर आपका पैटर्न नामक फ़ाइल से मेल खा सकता है -f, जो rmएक विकल्प के रूप में माना जाएगा।)

एक अन्य तरीका यह है ls -iकि फ़ाइल के इनकोड को खोजने के लिए कॉल किया जाए (इनोड विशिष्ट रूप से किसी दिए गए फाइल सिस्टम पर किसी फ़ाइल की पहचान करता है), फिर find -inumउस विशेष फ़ाइल पर काम करने के लिए। यह तरीका ज्यादातर उपयोगी होता है जब निर्देशिका में बहुत सारी फाइलें होती हैं।

ls -i
# note the inode number 12345
find . -xdev -inum 12345 -delete

यदि आपके findपास कोई -deleteविकल्प नहीं है , तो कॉल करें rm:

find . -xdev -inum 12345 -exec rm -- {} \;

(हां, मुझे पता है कि इसमें से अधिकांश पहले ही पोस्ट किए जा चुके हैं। लेकिन प्रासंगिक जानकारी वाले उत्तर इसे और अधिक जटिल बना रहे हैं, जितना कि यह होना चाहिए।)


4

echo -eचरित्र प्राप्त करने के लिए उपयोग करने की कोशिश करें \177, फिर xargsइसे पास करने के लिए rmechoदशमलव से बचना नहीं है, इसलिए हेक्स में परिवर्तित करें:177 ऑक्टल को चालू करता है; इससे पहले (शाब्दिक, शून्य बाइट नहीं) की echoआवश्यकता है \0:

echo -ne '\0177\0' | xargs -0 rm

क्या आप कह रहे हैं कि \ xb1 \ 0 हेक्स का प्रतिनिधित्व 177 है?
श्री मूस

@Mroseose \xb1दशमलव है 177, \0इसे शून्य-समाप्त करता है, और एक नई-समाप्ति वाले शब्द के बजाय एक शून्य-समाप्त नाम लेने के लिए -0कहता xargsहै।
केविन

मैं SunOS पर बैश का उपयोग कर रहा हूं और जब मैंने आपकी कमांड की कोशिश की, तो मुझे xargs मिला: अवैध विकल्प - 0. मैंने मैन पेज देखा और शून्य समाप्ति के लिए कोई विकल्प नहीं देखा। मैं अब इस मुद्दे के लिए एक तय पाने में कामयाब रहा। जवाब के रूप में चिह्नित प्रतिक्रिया देखें।
श्री मूस

आपका echo, जैसा-है, xargs में 2 फ़ाइल नाम भेजता है , और फिर rm... दूसरी फ़ाइल का नाम है \n.. इसका परिणाम या तो एक त्रुटि है, या उस नाम ('\ n') की फ़ाइल को हटाना है
पीटर। ओ

@perer हां, मैंने अभी गौर किया है। मैंने -nनई लाइन से छुटकारा पाने के लिए जोड़ा ।
केविन

3

मैं बस के बारे में आप गारंटी ले सकते हैं कि फ़ाइल करता है एक नाम है। यह सिर्फ एक नाम होता है जिसमें गैर-मुद्रण योग्य वर्ण होते हैं।

अगर rmकाम नहीं किया, तो विकल्प के findसाथ आउटपुट का उपयोग -inumतर्क के रूप में rmमदद करने की संभावना नहीं है; यह सिर्फ उसी तर्क को पारित करने जा रहा है rm, उसी समस्या के साथ।

फ़ाइल उस निर्देशिका में केवल एक ही है, है ना?

पहली चीज़ जो मैंने कोशिश की है cdवह निर्देशिका में है, फिर टाइप करें rm ./, फिर टैब कुंजी दबाएं। यह फ़ाइल के वास्तविक नाम के तर्क का विस्तार करना चाहिए, और पूर्ववर्ती ./को rmतर्क को फ़ाइल नाम के अलावा किसी अन्य चीज़ के रूप में व्याख्या करने से रोकना चाहिए ।

एक अन्य समाधान cdमूल निर्देशिका के लिए है, तो निर्देशिका पर rm -r(या, यदि आवश्यक हो, rm -rf) का उपयोग करें । नाम की परवाह किए बिना, निर्देशिका और उसकी सभी सामग्रियों को हटा देना चाहिए। फिर आप mkdirनिर्देशिका को फिर से बनाने के लिए उपयोग कर सकते हैं (और शायद chmodइसकी अनुमति बहाल करने के लिए)।

संपादित करें:

आपके ls -lbआउटपुट को फिर से देखते हुए , मुझे लगता है कि फ़ाइल का नाम ASCII DELवर्ण से शुरू होता है (जो बुरा नहीं घातक है) और इसमें एक या एक से अधिक न्यूलाइन वर्ण होते हैं (जो वास्तव में बुरा है)। जहाँ तक मैं बता सकता हूँ, rmकमांड एक फ़ाइल नाम के हिस्से के रूप में एक नई पंक्ति की व्याख्या नहीं कर सकता है।

लेकिन unlink()सिस्टम कॉल कर सकता है। यहां एक पर्ल स्क्रिप्ट है, जिसे मैंने एक साथ फेंक दिया है जो वर्तमान निर्देशिका में फ़ाइलों के माध्यम से पुनरावृति करेगा, और आपसे हर एक के लिए पूछेगा कि क्या आप इसे निकालना चाहते हैं। यह rmफ़ाइलों को हटाने के लिए किसी बाहरी कमांड का उपयोग नहीं करता है , इसलिए यह किसी भी मज़ेदार पात्रों को संभालने में सक्षम होना चाहिए जो फ़ाइल सिस्टम का समर्थन करता है (ASCII के अलावा NULऔर कुछ भी /)।

करने rm -rया rm -rfयुक्त निर्देशिका पर अभी भी काम करना चाहिए, लेकिन यदि आप केवल एक फ़ाइल को निकालना चाहते हैं तो आप यह कोशिश कर सकते हैं।

#!/usr/bin/perl

use strict;
use warnings;

opendir my $DIR, '.' or die ".: $!\n";
my @files = sort grep { -f } readdir $DIR;
closedir $DIR;

foreach my $file (@files) {
    my $pfile = printable($file);
    print "Remove $pfile? ";
    my $answer = scalar <STDIN>;
    if ($answer =~ /^[Yy]/) {
        print "Removing $pfile\n";
        unlink $file or warn "Unable to remove $pfile: $!\n";
    }
}

sub printable {
    my($s) = @_;
    $s =~ s/[^ -~]/?/g;
    return $s;
}

(एक अन्य समाधान, यदि निर्देशिका में अन्य फाइलें हैं जिन्हें आप रखना चाहते हैं, तो अन्य सभी फाइलों को एक अस्थायी निर्देशिका में स्थानांतरित करना है, फिर निर्देशिका को फिर से बनाना और अन्य फ़ाइलों को वापस करना है।)

(ओह, और जो कुछ भी आपने उस फ़ाइल को बनाने के लिए किया था, उसे दोबारा न करने की कोशिश करें!)


1

यदि आप कमांड का उपयोग करके वास्तव में उस फ़ाइल को पा सकते हैं find, तो आप -deleteविधेय का उपयोग कर सकते हैं । बस सावधान रहें, और -deleteकमांड खोजने का अंतिम पैरामीटर बनाएं या इसे बहुत नुकसान होगा ...


1

आप पास में हैं। चरण-दर-चरण, यहां इनकोड संख्या द्वारा फ़ाइल को हटाने का तरीका बताया गया है।

सबसे पहले, आप जिस फ़ाइल का उपयोग करना चाहते हैं, उसका इनकोड नंबर ढूंढें ls -li। इनकोड संख्या आउटपुट के पहले कॉलम में होगी।

उदाहरण के लिए:

$ls -li
311010 -rw-rw-r-- 1 me me 3995 Apr  6 16:27 -???\# ;-)

इस स्थिति में, इनोड संख्या 311010 है

findइनकोड संख्या द्वारा फ़ाइल देखने के लिए उपयोग करें ।

find . -inum 311010 

सुनिश्चित करें कि findकेवल उस फ़ाइल का नाम लौटाएं जिसे आप हटाना चाहते हैं। उदाहरण के लिए:

$find . -inum 311010
./-???\# ;-)

एक बार जब आप सुनिश्चित कर लें कि findसही फ़ाइल मिल रही है, तो -deleteपैरामीटर को पास करें find। यह आपके लिए फ़ाइल को हटा देगा।

find . -inum 311010 -delete

0

अन्य उत्तर महान हैं और लगभग सभी वातावरणों में काम करेंगे।

लेकिन, यदि आप एक गुई चल रहे हैं, तो बस निर्देशिका को nautilus, डॉल्फ़िन, कोनेकर, या अपने पसंदीदा फ़ाइल प्रबंधक में खोलें और आपको आसानी से किसी भी फ़ाइल को देखने और हटाने में सक्षम होना चाहिए जिसमें एक माउस क्लिक के साथ एक अपरंपरागत नाम है ।

यदि आप एक नियमित emacs या vim उपयोगकर्ता नहीं हैं (जैसा कि कई अन्य उत्तरों में दिखाया गया है), यह जाने का सबसे आसान तरीका हो सकता है।


0

"\ 033" (वास्तविक "एस्केप" वर्ण) नामक फ़ाइल के साथ एक समान समस्या थी।

for x in $( ls | awk '!/^[A-Z]/ && !/^[a-z]/ && !/^[0-9]/');do rm -i -- $x ; done

उपरोक्त आपको वर्तमान निर्देशिका में फ़ाइलों को हटाने के लिए संकेत देगा जो एक पत्र या संख्या से शुरू नहीं होते हैं।


0

इसके बजाय, आप वर्तमान निर्देशिका का नाम बदल सकते हैं, नाम के DirX_OLDसाथ एक नई निर्देशिका बना सकते हैं DirXऔर सभी आवश्यक फ़ाइलों को इससे स्थानांतरित DirX_OLDकर सकते हैं DirX। फ़ाइलों को कॉपी करने के बाद आप हटा सकते हैंDirX_OLD


0

बस मामले में यह किसी को भी मदद करता है मैं अपने दो सेंट के लायक जोड़ दूंगा। मैं statवाइल्डकार्ड पर इस तरह से फाइल का नाम प्राप्त करने में सक्षम था :

stat -c %N *

आउटपुट:

`\220g\201\acontexts'
`\220g\201\alogins'
`\220g\201\amodules'
`\220g\201\apolicy'
`\220g\201\asetrans.conf'

तब मैं एएनएसआई सी-उद्धृत स्ट्रिंग्स का उपयोग कर सकता था (जैसा कि स्वीकृत उत्तर में उपयोग किया जाता है) फाइलों तक पहुंचने के लिए:

rm $'\220g\201\asetrans.conf'

0

हर फ़ाइल का एक नाम होता है, आपको बस वही ढूंढना होगा जो

मैं उदाहरण के रूप में इस फाइल का उपयोग करूंगा:

$ touch $'\177' $'\001\002' $'\033\027' a b abc $'a\177b'

वे फाइलें ?सामान्य रूप में दिखाई देंगी ls:

$ ls
??  ?  ?002  a  abc  b

लेकिन अगर आपका विकल्प lsअनुमति देता है तो -Qयह स्पष्ट होना चाहिए कि वास्तविक फ़ाइल नाम क्या है:

$ ls -1iQ *
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"
26739118 "a"
26739121 "a\177b"
26739120 "abc"
26739119 "b"

वे 1pwd में फ़ाइलों के कॉलम में इनकोड संख्या और "उद्धरण" नाम हैं ।

विस्तार (ग्लोबिंग) का उपयोग करने के लिए एक (POSIX) शेल की निवास स्थान का उपयोग कर रहा है:

किसी भी गैर-मुद्रण वर्ण वाले नाम रखने के लिए:

$ ls -1iQ *[![:print:]]*
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"
26739121 "a\177b"

और केवल गैर-मुद्रण वर्ण वाली फ़ाइलों को सूचीबद्ध करने के लिए :

$ ls -1iQ [![:print:]]*
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"

फिर, चयन करने के लिए -i((इंटरैक्टिव) विकल्प) उन्हें उपयोग को हटा दें:

$ rm -i [![:print:]]*
rm: remove regular file ''$'\001\002'? n
rm: remove regular file ''$'\033\027'? n
rm: remove regular file ''$'\177'? n

आपको बस यह चुनने की जरूरत yहै कि ऊपर दिए गए प्रश्न का उत्तर देकर आपको कौन सा मिटा देना है।


0

यदि आपके पास स्वतः पूर्णता के साथ बैश है, तो यह आपके लिए काम कर सकता है। मैंने उस चरित्र को टाइप किया जो निर्देशिका लिस्टिंग में दिखाया गया था। फिर मैंने स्वत: पूर्णता को ट्रिगर किया और इस चीज़ को कुछ प्रिंट करने योग्य नाम दिया।

यहाँ मेरे लिए क्या काम किया गया है:

$ ll
-rw-r--r--.  1 xxxxxxxx  xxxxx 25608 Oct 11 11:11 ?
$ mv ?  
(hit the [tab] and it gets extended to ...)
$ mv ^[
(now complete the command and rename to something printable)
$ mv ^[ weirdchar
$ ll
-rw-r--r--.  1 xxxxxxxx  xxxxx 25608 Oct 11 11:11 weirdchar
(now delete)
$ rm weirdchar

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.