रिक्त स्थान के साथ 'फाइंड -सेक्स' पास फ़ाइल नाम कैसे करता है?


14

अगर मेरे पास एक निर्देशिका है जिसमें कुछ फाइलें हैं जिनके नाम में रिक्त स्थान हैं, उदाहरण के लिए

$ ls -1 dir1
file 1
file 2
file 3

मैं उन सभी को सफलतापूर्वक इस तरह एक और निर्देशिका में कॉपी कर सकता हूं:

$ find dir1 -mindepth 1 -exec cp -t dir2 {} +

हालाँकि, find dir1 -mindepth 1अन-एस्केप किए गए रिक्त स्थान में आउटपुट शामिल हैं:

$ find dir1 mindepth 1
dir1/file 1
dir1/file 3
dir1/file 3

यदि मैं print0इसके बजाय का उपयोग करता हूं print, तो आउटपुट में अभी भी अन-एस्केप स्थान शामिल हैं:

$ find dir1 mindepth 1 -print0
dir1/file 1dir1/file 2dir1/file 3

मैन्युअल रूप से इन फ़ाइलों की प्रतिलिपि बनाने के लिए cp, मुझे रिक्त स्थान से बचने की आवश्यकता होगी; लेकिन ऐसा लगता है कि यह अनावश्यक है जब cpसे आ रहा है find, चाहे मैं का उपयोग करें +या \;आदेश के अंत में।

इसका क्या कारण है?

जवाबों:


8

findआदेश सीधे आदेश निष्पादित करता है। फ़ाइल नाम तर्क सहित कमांड को शेल या किसी और चीज़ द्वारा संसाधित नहीं किया जाएगा जो फ़ाइल नाम को संशोधित कर सकता है। यह बहुत सुरक्षित है।

आप सही हैं कि उन फ़ाइलनामों से बचने की कोई आवश्यकता नहीं है, जिनके द्वारा प्रतिनिधित्व किया जाता है {}find कमांड लाइन पर ।

findडिस्क से कच्चे फ़ाइलनाम को सीधे -execकमांड की आंतरिक तर्क सूची में , आपके मामले में, cpकमांड में पास करता है।


1
संक्षेप में, find..execअपने दम पर अजीब फ़ाइल नाम संभाल सकते हैं ..
heemayl

2
लिनक्स क्लब का पहला नियम है कि आप पार्स नहीं करते हैं
सर्गी कोलोडियाज़नी

5

सवाल दो-भाग है:

  • कैसे का उपयोग कर कॉल कार्यक्रमों का प्रबंधन करता है find-execफ़ाइल नाम में एम्बेड किए गए रिक्त स्थान के साथ समस्याओं किए बिना , और
  • क्या अच्छा -print0विकल्प है?

पहले के लिए, findएक सिस्टम कॉल कर रहा है, वास्तव में संबंधित कॉल के एक समूह को "निष्पादन" के रूप में संदर्भित किया जाता है। । यह फ़ाइल नाम को सीधे इस कॉल के तर्क के रूप में पास करता है, जो तब फ़ाइल नाम के बारे में जानकारी खोए बिना सीधे (एक नई प्रक्रिया बनाने के बाद) पारित किया जाता है।

POSIX findसुविधा +को इस प्रकार समझाया गया है, औचित्य में :

SVR4 की findउपयोगिता की एक विशेषता -execप्राथमिक + टर्मिनेटर थी। इसने विशेष वर्णों (विशेषकर नई वर्णों) वाले फ़ाइलनामों को उन समस्याओं के बिना एक साथ समूहीकृत करने की अनुमति दी, यदि ऐसे फ़ाइलनामों को पाइप किया जाता है xargs। अन्य कार्यान्वयन ने इस समस्या को हल करने के लिए अन्य तरीकों को जोड़ा है, विशेष रूप से एक -print0प्राथमिक जो नल बाइट टर्मिनेटर के साथ फाइलनाम लिखा है। यह यहां माना जाता था, लेकिन अपनाया नहीं गया। नल टर्मिनेटर का उपयोग करने का मतलब है कि किसी भी उपयोगिता जो कि खोज के -print0आउटपुट को संसाधित करने जा रही थी, उसे शून्य टर्मर्स को पार्स करने के लिए एक नया विकल्प जोड़ना होगा जो अब पढ़ा जाएगा।

यह " विशेष रूप से एक -print0प्राथमिक" जीएनयू को संदर्भित करता है findऔर xargsजो समस्या को एक अलग तरीके से हल करता है। यह भी FreeBSD के द्वारा समर्थित है findऔर xargs। यदि आपने कॉल में एक -0विकल्प ( मैनुअल पेज देखें ) जोड़ा है xargs, तो वह प्रोग्राम "नल बाइट" वर्णों द्वारा समाप्त लाइनों को स्वीकार करता है। बदले में, अपने काम करने के लिए निष्पादन-xargs कॉल को कॉल करता है। और फीचर बनाम फीचर के बीच मुख्य अंतर यह है कि पूर्व एक पाइप के ऊपर से फाइलनाम पास करता है, जबकि बाद वाला नहीं करता है। डेवलपर्स लगभग किसी भी सुविधा के लिए उपयोग करता है; पाइप कोई अपवाद नहीं हैं।-print0-0+

वापस ओपी के उदाहरण के लिए, जो एक -tविकल्प का उपयोग करता है cp: जो कि POSIX cp में नहीं पाया जाता है । बल्कि, यह GNU cp द्वारा प्रदान किया गया एक एक्सटेंशन (उर्फ "नॉनस्टैंडर्ड फीचर") है । के -0विस्तार से xargsइस उदाहरण में सुधार नहीं होगा, लेकिन ऐसे अन्य मामले भी हैं जहां इसका प्रभावी ढंग से उपयोग किया जा सकता है - यह ध्यान में रखते हुए कि पोर्टेबल विकल्प है +, जिसे जीएनयू findस्वीकार करता है।


-1

( यह एक टिप्पणी होनी चाहिए लेकिन यह बहुत बड़ी है। )

उन लोगों के लिए जो चीजों को आज़माना चाहते हैं:

एक स्क्रिप्ट लिस्टिंग स्थितीय पैरामीटर बनाएँ, जिसमें कॉल किया गया हो list_positional_parameters.sh

#!/bin/bash

# http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html
# Try globbing patterns, e.g. "X[[:digit:]][[:digit:]]" to see what happens

if [ $# -lt 1 ]; then
   echo "Usage: $0 and then at least one parameter"
   exit 1
fi

counter=1

while (($#)); do
   echo "$counter = '$1'"
   # pop positional argument 1 off the stack of positional arguments
   shift
   (( counter++ ))
done

findकुछ निर्देशिका $ dir पर इसके साथ चलाएँ :

find "$dir" -exec ./list_positional_parameters.sh '{}' ';' | less

जैसा कि अपेक्षित था, सभी कॉल में केवल एक ही पैरामीटर है, फ़ाइल नाम, चाहे उसके नाम में रिक्त स्थान हों या नहीं।


1
तुम भी उपयोग कर सकते हैं printfकी तरह printf '"%s"\n' "$@"सभी स्थितीय तर्क उद्धृत किया, दृश्य निरीक्षण के लिए बाहर मुद्रित करने के लिए।
Kusalananda
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.