मेरा वर्तमान सर्वश्रेष्ठ दांव है:
for i in $(find . -name *.jpg); do echo $i; done
समस्या: फ़ाइल नाम में रिक्त स्थान नहीं संभालती है।
नोट: मुझे ऐसा करने का एक चित्रमय तरीका भी पसंद आएगा, जैसे कि "ट्री" कमांड।
मेरा वर्तमान सर्वश्रेष्ठ दांव है:
for i in $(find . -name *.jpg); do echo $i; done
समस्या: फ़ाइल नाम में रिक्त स्थान नहीं संभालती है।
नोट: मुझे ऐसा करने का एक चित्रमय तरीका भी पसंद आएगा, जैसे कि "ट्री" कमांड।
जवाबों:
विहित तरीका है
find . -name '*.jpg' -exec echo {} \;
(की जगह \;
के साथ +
करने के लिए एक से अधिक फ़ाइल पारित करने के लिए echo
एक समय में)
या (जीएनयू विशिष्ट, हालांकि कुछ बीएसडी अब भी हैं):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
जो \b
( जैसे कम से कम यूनिक्स कंफर्मेंट echo
एस) से बचने के दृश्यों का विस्तार करता है ।
find
मैनपेज शो find . -type f -exec file '{}' \;
में EXAMPLES
अनुभाग। शायद कुछ गोले ब्रेसिज़ का विशेष रूप से इलाज करेंगे।
'{}'
, \{\}
, {}
, "{}"
, '{'}
खोल (जो भी बॉर्न-जैसा शेल) द्वारा एक तर्क है कि दो अक्षर है खोजने के लिए "{" और "}" का विस्तार कर रहे हैं। "खोजो" को "प्रतिध्वनी खोजें" से बदलें, या printf '<%s>\n' find
यदि आप डबल-चेक करना चाहते हैं।
बेहतर जवाब पहले ही दिए जा चुके हैं।
लेकिन ध्यान दें कि आपके द्वारा दिए गए कोड में रिक्त स्थान एकमात्र समस्या नहीं है। टैब, न्यूलाइन और वाइल्डकार्ड वर्ण भी एक समस्या है।
साथ में
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
तब केवल न्यूलाइन वर्ण ही एक समस्या है।
आपने जो उल्लेख किया है, वह उन बुनियादी समस्याओं में से एक है, जिनका लोग सामना करते हैं, जब वे फ़ाइल नाम पढ़ने की कोशिश करते हैं। कभी-कभी, सीमित ज्ञान और फ़ाइल और फ़ोल्डर संरचना की गलत धारणा वाले लोग यह भूल जाते हैं कि " UNIX सब कुछ एक फ़ाइल है "। इसलिए वे यह नहीं समझते कि उन्हें रिक्त स्थान को संभालने की आवश्यकता है, क्योंकि फ़ाइल नाम में रिक्त स्थान के साथ 2 या अधिक शब्द हो सकते हैं।
समाधान: ऐसा करने का एक बेहतर ज्ञात तरीका यह है कि एक साफ पढ़ा जाए ।
हम यहां मौजूद सभी फाइलों को पढ़ेंगे और उन्हें एक चर में रखेंगे, अगली बार जब वांछित प्रसंस्करण करते हैं तो हमें बस उस चर को उद्धरणों के अंदर रखना होगा जो रिक्त स्थान के साथ फ़ाइल नामों को संरक्षित करेगा। यह इसे करने के मूल तरीकों में से एक है, हालांकि, अन्य लोगों द्वारा यहां दिए गए अन्य उत्तर बस के रूप में भी काम करते हैं।
SCRIPT:
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
यहाँ मैं उन्हें पथ देकर फाइलें पढ़ रहा हूं और जो कुछ भी मैं पढ़ रहा हूं, उन्हें एक चर के अंदर रख रहा हूं, जिसे मैं बाद में एक बिंदु पर उद्धृत करूंगा, ताकि रिक्त स्थान को संरक्षित करने के लिए इसे संसाधित किया जा सके।
आशा है कि यह आपको किसी तरह से मदद करेगा।
बस के साथ find
और bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
इस तरह, हम उपयोग करते हैं $1
बैश में , एक मूल स्क्रिप्ट की तरह, जो किसी भी उन्नत (या नहीं) कार्यों को करने के लिए अच्छा दृष्टिकोण खोलते हैं।
एक अधिक कुशल तरीका (हर फ़ाइल के लिए एक नया बैश शुरू करने से बचने के लिए):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
बैश के हालिया संस्करण में, आप globstar
विकल्प का उपयोग कर सकते हैं :
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
साधारण कार्यों के लिए, आप पूरी तरह से लूप छोड़ सकते हैं:
echo **/*.jpg
set -G
), इसका उपयोग bash में नहीं किया जाना चाहिए क्योंकि bash संस्करण मूलभूत रूप से टूटा हुआ है (GNU की तरह grep -r
) क्योंकि यह निर्देशिकाओं ( find -L
zsh या समकक्ष) के सहानुभूति में उतरता है ***/*.jpg
)। यह भी ध्यान दें कि खोजने के विपरीत, यह डॉटफ़िल्स को ommit करेगा और dotdirs में नहीं उतरेगा (डिफ़ॉल्ट रूप से)।
$i
? मैं ऐसा करता हूं और यह ठीक काम करता है। क्या उस दृष्टिकोण में कुछ गड़बड़ है?