मैं बैश लूप सूची में सफेद स्थान से कैसे बच सकता हूं?


121

मेरे पास एक बैश शेल स्क्रिप्ट है जो एक निश्चित डायरेक्टरी के सभी चाइल्ड डायरेक्टरीज़ (लेकिन फाइल नहीं) के माध्यम से लूप करती है। समस्या यह है कि कुछ निर्देशिका नामों में रिक्त स्थान होते हैं।

यहाँ मेरे परीक्षण निर्देशिका की सामग्री हैं:

$ls -F test
Baltimore/  Cherry Hill/  Edison/  New York City/  Philadelphia/  cities.txt

और कोड जो निर्देशिकाओं के माध्यम से लूप करता है:

for f in `find test/* -type d`; do
  echo $f
done

यहाँ उत्पादन है:

परीक्षा / बाल्टीमोर
परीक्षा / चेरी
पहाड़ी
परीक्षा / एडीसन 
परीक्षण / नई
यॉर्क
Faridabad
परीक्षा / फिलाडेल्फिया

चेरी हिल और न्यूयॉर्क शहर को 2 या 3 अलग प्रविष्टियों के रूप में माना जाता है।

मैंने फिल्म के नामों को उद्धृत करने की कोशिश की, जैसे:

for f in `find test/* -type d | sed -e 's/^/\"/' | sed -e 's/$/\"/'`; do
  echo $f
done

लेकिन कोई फायदा नहीं हुआ।

ऐसा करने का एक सरल तरीका है।


नीचे दिए गए जवाब बहुत अच्छे हैं। लेकिन इसे और अधिक जटिल बनाने के लिए - मैं हमेशा अपने परीक्षण निर्देशिका में सूचीबद्ध निर्देशिकाओं का उपयोग नहीं करना चाहता। कभी-कभी मैं निर्देशिका नामों को इसके बजाय कमांड-लाइन मापदंडों के रूप में पारित करना चाहता हूं।

IFS को स्थापित करने के लिए मैंने चार्ल्स का सुझाव लिया और निम्नलिखित बातों के साथ आया:

dirlist="${@}"
(
  [[ -z "$dirlist" ]] && dirlist=`find test -mindepth 1 -type d` && IFS=$'\n'
  for d in $dirlist; do
    echo $d
  done
)

और यह ठीक काम करता है जब तक कि कमांड लाइन के तर्कों में स्थान नहीं हैं (भले ही उन तर्कों को उद्धृत किया गया हो)। उदाहरण के लिए, इस तरह से स्क्रिप्ट को कॉल करना: test.sh "Cherry Hill" "New York City"निम्नलिखित आउटपुट उत्पन्न करता है:

चेरी
पहाड़ी
नया
यॉर्क
Faridabad

पुन: संपादित करें, list="$@"मूल मान सूची-नेस को पूरी तरह से अलग करता है, इसे एक स्ट्रिंग में ढहता है। कृपया मेरे उत्तर में दिए गए निर्देशों का पालन करें - इस तरह के असाइनमेंट को उसमें कहीं भी प्रोत्साहित नहीं किया जाता है; यदि आप किसी प्रोग्राम में कमांड-लाइन तर्कों की एक सूची पास करना चाहते हैं, तो आपको उन्हें एक सरणी में इकट्ठा करना चाहिए, और उस सरणी को सीधे विस्तारित करना चाहिए।
चार्ल्स डफी

जवाबों:


105

सबसे पहले, इस तरह से मत करो। सबसे अच्छा तरीका find -execठीक से उपयोग करना है:

# this is safe
find test -type d -exec echo '{}' +

अन्य सुरक्षित दृष्टिकोण एनयूएल-टर्मिनेटेड सूची का उपयोग करना है, हालांकि इसके लिए यह आवश्यक है कि आपका समर्थन खोजें -print0:

# this is safe
while IFS= read -r -d '' n; do
  printf '%q\n' "$n"
done < <(find test -mindepth 1 -type d -print0)

आप किसी सरणी को खोजने से भी रोक सकते हैं, और बाद में उस सरणी को पास कर सकते हैं:

# this is safe
declare -a myarray
while IFS= read -r -d '' n; do
  myarray+=( "$n" )
done < <(find test -mindepth 1 -type d -print0)
printf '%q\n' "${myarray[@]}" # printf is an example; use it however you want

यदि आपकी खोज का समर्थन नहीं करता है -print0, तो आपका परिणाम असुरक्षित है - नीचे दी गई इच्छानुसार व्यवहार नहीं किया जाएगा यदि फाइलें उनके नाम में नईलाइनों के साथ मौजूद हैं (जो कि, हां, कानूनी है)

# this is unsafe
while IFS= read -r n; do
  printf '%q\n' "$n"
done < <(find test -mindepth 1 -type d)

यदि कोई उपरोक्त में से एक का उपयोग नहीं करने जा रहा है, तो तीसरा दृष्टिकोण (समय और स्मृति उपयोग दोनों के संदर्भ में कम कुशल है, क्योंकि यह शब्द-विभाजन करने से पहले उपप्रकार के पूरे आउटपुट को पढ़ता है) एक IFSचर का उपयोग करना है जो doesn 't में स्पेस कैरेक्टर होता है। ग्लोबिंग ( set -f) को बंद करें ताकि ग्लोब कैरेक्टर वाले स्ट्रिंग्स को रोका जा सके [], *या ?विस्तार किया जा सके:

# this is unsafe (but less unsafe than it would be without the following precautions)
(
 IFS=$'\n' # split only on newlines
 set -f    # disable globbing
 for n in $(find test -mindepth 1 -type d); do
   printf '%q\n' "$n"
 done
)

अंत में, कमांड-लाइन पैरामीटर केस के लिए, आपको एरेज़ का उपयोग करना चाहिए, यदि आपका शेल उन्हें सपोर्ट करता है (यानी यह ksh, bash या zash):

# this is safe
for d in "$@"; do
  printf '%s\n' "$d"
done

जुदाई बनाए रखेगा। ध्यान दें कि उद्धरण (और इसके $@बजाय का उपयोग $*) महत्वपूर्ण है। एरे को अन्य तरीकों से भी आबाद किया जा सकता है, जैसे कि ग्लोब एक्सप्रेशन:

# this is safe
entries=( test/* )
for d in "${entries[@]}"; do
  printf '%s\n' "$d"
done

1
उस '+' स्वाद के बारे में पता नहीं था -exec। मीठा
जोहानस शाउब -

1
ऐसा लगता है कि यह xargs की तरह भी हो सकता है, केवल दिए गए कमांड के अंत में तर्क रखें: / कि मुझे कभी
गुस्सा आ रहा है - जोहानस शहाब -

मुझे लगता है कि -exec [नाम] {} + एक GNU और 4.4-BSD एक्सटेंशन है। (कम से कम, यह सोलारिस 8 पर प्रकट नहीं होता है, और मुझे नहीं लगता कि यह एआईएक्स 4.3 में भी था।) मुझे लगता है कि हम में से बाकी लोग xargs से पाइपिंग के साथ फंस सकते हैं ...
माइकल रतनपिन्था

2
मैंने पहले कभी $ '\ n' सिंटैक्स नहीं देखा है। वह कैसे काम करता है? (मुझे लगा होगा कि IFS = '\ n' या IFS = "\ n" काम करेगा, लेकिन न तो करता है।)
MCS

1
@ क्रोसस्टॉक यह निश्चित रूप से सोलारिस 10 में है, मैंने अभी इसका उपयोग किया है।
निक

26
find . -type d | while read file; do echo $file; done

हालाँकि, अगर फ़ाइल-नाम में नई सुर्खियाँ हों तो काम नहीं करता। उपरोक्त एकमात्र समाधान है जो मुझे पता है कि आप वास्तव में एक चर में निर्देशिका का नाम कैसे चाहते हैं। यदि आप बस कुछ कमांड निष्पादित करना चाहते हैं, तो xargs का उपयोग करें।

find . -type d -print0 | xargs -0 echo 'The directory is: '

Xargs की कोई आवश्यकता नहीं, ढूँढें -exec देखें ... {} +
चार्ल्स डफी

4
@Charles: बड़ी संख्या में फ़ाइलों के लिए, xargs बहुत अधिक कुशल है: यह केवल एक प्रक्रिया को जन्म देती है। प्रत्येक फ़ाइल के लिए -exec विकल्प एक नई प्रक्रिया की मांग करता है, जो परिमाण धीमे का एक क्रम हो सकता है।
एडम रोसेनफील्ड

1
मुझे xargs ज्यादा पसंद है। इन दोनों अनिवार्य रूप से, एक ही दोनों लगते हैं, जबकि xargs, और अधिक विकल्प हैं साथ में चल रहे की तरह
litb - Johannes Schaub

2
एडम, नहीं कि '+' एक के रूप में संभव के रूप में कई फ़ाइल नाम एकत्र करेगा और फिर निष्पादित करता है। लेकिन यह समानांतर में :) चल के रूप में इस तरह के साफ कार्यों के लिए नहीं होगा
litb - Johannes Schaub

2
ध्यान दें कि यदि आप फ़ाइल नाम के साथ कुछ करना चाहते हैं, तो आपको उन्हें उद्धृत करना होगा। जैसे:find . -type d | while read file; do ls "$file"; done
डेविड मोल्स

23

यहाँ एक सरल समाधान है जो फ़ाइल नाम में टैब और / या व्हाट्सएप को संभालता है। यदि आपको नए नाम जैसे फ़ाइल नाम में अन्य अजीब पात्रों से निपटना है, तो एक और उत्तर चुनें।

परीक्षण निर्देशिका

ls -F test
Baltimore/  Cherry Hill/  Edison/  New York City/  Philadelphia/  cities.txt

निर्देशिका में जाने के लिए कोड

find test -type d | while read f ; do
  echo "$f"
done

फ़ाइल नाम उद्धृत किया जाना चाहिए ( "$f") यदि तर्क के रूप में उपयोग किया जाता है। उद्धरण के बिना, रिक्त स्थान विभाजक के रूप में कार्य करते हैं और इनवॉइस किए गए आदेश पर कई तर्क दिए जाते हैं।

और आउटपुट:

test/Baltimore
test/Cherry Hill
test/Edison
test/New York City
test/Philadelphia

धन्यवाद, यह उर्फ ​​मैं काम कर रहा था, जो यह बताने के लिए बना रहा था कि वर्तमान फ़ोल्डर में प्रत्येक निर्देशिका कितनी जगह का उपयोग कर रही है, यह पिछले अवतार में रिक्त स्थान के साथ कुछ dirs पर घुट रहा था। यह zsh में काम करता है, लेकिन कुछ अन्य उत्तर नहीं थे:alias duc='ls -d * | while read D; do du -sh "$D"; done;'
टेड नालेड

2
यदि आप zsh का उपयोग कर रहे हैं, तो आप यह भी कर सकते हैं:alias duc='du -sh *(/)'
cbliard

@cbliard यह अभी भी छोटी गाड़ी है। इसे एक फ़ाइल नाम के साथ चलाने का प्रयास करें, कहते हैं, एक टैब अनुक्रम, या कई रिक्त स्थान; आप ध्यान देंगे कि यह उनमें से किसी एक स्थान को बदलता है, क्योंकि आप अपनी प्रतिध्वनि में उद्धृत नहीं कर रहे हैं। और फिर नए नामों वाली फ़िल्मों का मामला है ...
चार्ल्स डफी

@CharlesDuffy मैंने टैब अनुक्रमों और कई स्थानों के साथ प्रयास किया। यह उद्धरण के साथ काम करता है। मैंने नई कहानियों के साथ भी कोशिश की और यह बिल्कुल भी कारगर नहीं है। मैंने उसी हिसाब से जवाब अपडेट किया। इस बारे में बताने के लिए शुक्रिया।
cbliard

1
@cbliard राइट - अपने इको कमांड में उद्धरण जोड़ना जो मुझे मिल रहा था। के रूप में newlines के लिए, आप पाते हैं -print0और का उपयोग करके उस काम कर सकते हैं IFS='' read -r -d '' f
चार्ल्स डफी

7

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


4

सिर्फ क्यों नहीं डाला गया

IFS='\n'

कमांड के लिए सामने? यह क्षेत्र विभाजक को <Space> <Tab> <Newline> से केवल <Newline> में बदल देता है


4
find . -print0|while read -d $'\0' file; do echo "$file"; done

1
-d $'\0'यह ठीक उसी तरह है -d ''- क्योंकि बैश NUL- टर्मिनेटेड स्ट्रिंग्स का उपयोग करता है, एक खाली स्ट्रिंग का पहला वर्ण NUL है, और उसी कारण से, NUL को C स्ट्रिंग्स के अंदर बिल्कुल भी नहीं दिखाया जा सकता है।
चार्ल्स डफी

4

मैं उपयोग करता हूं

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in $( find "$1" -type d ! -path "$1" )
do
  echo $f
done
IFS=$SAVEIFS

क्या यह पर्याप्त नहीं होगा? Http://www.eaberciti.biz/tips/handling-filenames-with-spaces-in-bash.html
से लिया गया आइडिया


शानदार टिप: यह एक कमांड-लाइन ऑसस्क्रिप्ट (OS X AppleScript) के विकल्पों के लिए बहुत मददगार है, जहां रिक्त स्थान एक तर्क को कई मापदंडों में विभाजित करते हैं, जहां केवल एक ही उद्देश्य है
tim

नहीं, यह पर्याप्त नहीं है। यह अक्षम है (अनावश्यक उपयोग के कारण $(echo ...)), ग्लोब एक्सप्रेशन के साथ फिल्नाम को सही तरीके से हैंडल नहीं करता है, इसमें फिलेंम्स को हैंडल नहीं करता है जिसमें $'\b''\ n' अक्षर सही हैं, और इसके अलावा व्हॉट्सएप के कई रन को सिंगल व्हाट्सएप कैरेक्टर में कन्वर्ट करता है। गलत उद्धरण के कारण आउटपुट पक्ष।
चार्ल्स डफी

4

सूची को स्ट्रिंग के रूप में संग्रहीत न करें; इस सभी भ्रम भ्रम से बचने के लिए उन्हें सरणियों के रूप में संग्रहीत करें। यहां एक उदाहरण स्क्रिप्ट दी गई है जो या तो परीक्षण की सभी उपनिर्देशिकाओं पर काम करेगी, या इसकी कमांड लाइन पर आपूर्ति की गई सूची:

#!/bin/bash
if [ $# -eq 0 ]; then
        # if no args supplies, build a list of subdirs of test/
        dirlist=() # start with empty list
        for f in test/*; do # for each item in test/ ...
                if [ -d "$f" ]; then # if it's a subdir...
                        dirlist=("${dirlist[@]}" "$f") # add it to the list
                fi
        done
else
        # if args were supplied, copy the list of args into dirlist
        dirlist=("$@")
fi
# now loop through dirlist, operating on each one
for dir in "${dirlist[@]}"; do
        printf "Directory: %s\n" "$dir"
done

आइए अब इसे एक परीक्षण निर्देशिका पर एक वक्र या दो फेंके के साथ देखें:

$ ls -F test
Baltimore/
Cherry Hill/
Edison/
New York City/
Philadelphia/
this is a dirname with quotes, lfs, escapes: "\''?'?\e\n\d/
this is a file, not a directory
$ ./test.sh 
Directory: test/Baltimore
Directory: test/Cherry Hill
Directory: test/Edison
Directory: test/New York City
Directory: test/Philadelphia
Directory: test/this is a dirname with quotes, lfs, escapes: "\''
'
\e\n\d
$ ./test.sh "Cherry Hill" "New York City"
Directory: Cherry Hill
Directory: New York City

1
इस पर पीछे मुड़कर देखें - वास्तव में POSIX श के साथ एक समाधान था : आप "$@"सरणी का पुन: उपयोग कर सकते हैं , इसके साथ संलग्न set -- "$@" "$f"
चार्ल्स डफी

4

आप अस्थायी रूप से IFS (आंतरिक क्षेत्र विभाजक) का उपयोग कर सकते हैं:

OLD_IFS=$IFS     # Stores Default IFS
IFS=$'\n'        # Set it to line break
for f in `find test/* -type d`; do
    echo $f
done

$IFS=$OLD_IFS


कृपया स्पष्टीकरण प्रदान करें।
स्टीव के।

IFS निर्दिष्ट करता है कि विभाजक प्रतीक क्या है, फिर सफेद स्थान के साथ फ़ाइल नाम को छोटा नहीं किया जाएगा।
आश्चर्यजनक

$ IFS = $ OLD_IFS अंत में होना चाहिए: IFS = $ OLD_IFS
मिशेल डॉना

3

पी एस अगर यह केवल इनपुट में जगह के बारे में है, तो कुछ दोहरे उद्धरणों ने मेरे लिए आसानी से काम किया ...

read artist;

find "/mnt/2tb_USB_hard_disc/p_music/$artist" -type f -name *.mp3 -exec mpg123 '{}' \;

2

जोनाथन ने जो कहा, उसे जोड़ने के लिए : निम्न के साथ संयोजन के -print0लिए विकल्प का उपयोग करें :findxargs

find test/* -type d -print0 | xargs -0 command

यह commandउचित तर्कों के साथ कमांड निष्पादित करेगा ; उनमें रिक्त स्थान वाली निर्देशिकाओं को ठीक से उद्धृत किया जाएगा (यानी उन्हें एक तर्क के रूप में पारित किया जाएगा)।


1
#!/bin/bash

dirtys=()

for folder in *
do    
 if [ -d "$folder" ]; then    
    dirtys=("${dirtys[@]}" "$folder")    
 fi    
done    

for dir in "${dirtys[@]}"    
do    
   for file in "$dir"/\*.mov   # <== *.mov
   do    
       #dir_e=`echo "$dir" | sed 's/[[:space:]]/\\\ /g'`   -- This line will replace each space into '\ '   
       out=`echo "$file" | sed 's/\(.*\)\/\(.*\)/\2/'`     # These two line code can be written in one line using multiple sed commands.    
       out=`echo "$out" | sed 's/[[:space:]]/_/g'`    
       #echo "ffmpeg -i $out_e -sameq -vcodec msmpeg4v2 -acodec pcm_u8 $dir_e/${out/%mov/avi}"    
       `ffmpeg -i "$file" -sameq -vcodec msmpeg4v2 -acodec pcm_u8 "$dir"/${out/%mov/avi}`    
   done    
done

उपरोक्त कोड .Mov फ़ाइलों को .avi में बदल देगा। .Mov फाइलें अलग-अलग फ़ोल्डर में होती हैं और फ़ोल्डर के नाम में सफेद स्थान भी होते हैं। मेरी उपरोक्त स्क्रिप्ट .mov फ़ाइलों को .avi फ़ाइल को उसी फ़ोल्डर में ही रूपांतरित करेगी। मुझे नहीं पता कि यह आपको लोगों की मदद करता है।

मामला:

[sony@localhost shell_tutorial]$ ls
Chapter 01 - Introduction  Chapter 02 - Your First Shell Script
[sony@localhost shell_tutorial]$ cd Chapter\ 01\ -\ Introduction/
[sony@localhost Chapter 01 - Introduction]$ ls
0101 - About this Course.mov   0102 - Course Structure.mov
[sony@localhost Chapter 01 - Introduction]$ ./above_script
 ... successfully executed.
[sony@localhost Chapter 01 - Introduction]$ ls
0101_-_About_this_Course.avi  0102_-_Course_Structure.avi
0101 - About this Course.mov  0102 - Course Structure.mov
[sony@localhost Chapter 01 - Introduction]$ CHEERS!

चीयर्स!


echo "$name" | ...काम नहीं करता nameहै -n, तो यह कैसे होता है और यह बैकस्लैश-एस्केप सीक्वेंस के साथ कैसे व्यवहार करता है , यह आपके कार्यान्वयन पर निर्भर करता है - POSIX echoउस मामले के व्यवहार को स्पष्ट रूप से अपरिभाषित बनाता है (जबकि XSI- विस्तारित POSIX बैकस्लैश-एस्केप सीक्वेंसेस के परिभाषित-मानक व्यवहार का विस्तार करता है , और GNU सिस्टम - जिसमें बैश भी शामिल है - बिना POSIXLY_CORRECT=1POSIX मानक को लागू किए बिना ब्रेक -e(जबकि आउटपुट पर echo -eप्रिंट करने की आवश्यकता होती है -e) printf '%s\n' "$name" | ...सुरक्षित है
चार्ल्स डफी

1

पाथने में व्हाट्सएप के साथ भी व्यवहार करना पड़ता था। मैंने आखिरकार एक पुनरावृत्ति का उपयोग क्या किया था और for item in /path/*:

function recursedir {
    local item
    for item in "${1%/}"/*
    do
        if [ -d "$item" ]
        then
            recursedir "$item"
        else
            command
        fi
    done
}

1
functionकीवर्ड का उपयोग न करें - यह आपके कोड को POSIX sh के साथ असंगत बनाता है, लेकिन इसका कोई अन्य उपयोगी उद्देश्य नहीं है। आप सिर्फ एक फ़ंक्शन को परिभाषित कर सकते हैं recursedir() {, दो Parens को जोड़ सकते हैं और फ़ंक्शन कीवर्ड को हटा सकते हैं, और यह सभी POSIX-compliant गोले के साथ संगत होगा।
चार्ल्स डफी

1

फ़ाइल सूची को बैश सरणी में बदलें। यह एक बैश फ़ंक्शन से एक सरणी वापस करने के लिए मैट मैकक्लेर के दृष्टिकोण का उपयोग करता है: http://notes-matthewlmcclure.blogspot.com/2009/12/return-array-from-bash-function-vind.html यह एक तरीका है किसी भी मल्टी-लाइन इनपुट को बैश एरे में बदलने के लिए।

#!/bin/bash

# This is the command where we want to convert the output to an array.
# Output is: fileSize fileNameIncludingPath
multiLineCommand="find . -mindepth 1 -printf '%s %p\\n'"

# This eval converts the multi-line output of multiLineCommand to a
# Bash array. To convert stdin, remove: < <(eval "$multiLineCommand" )
eval "declare -a myArray=`( arr=(); while read -r line; do arr[${#arr[@]}]="$line"; done; declare -p arr | sed -e 's/^declare -a arr=//' ) < <(eval "$multiLineCommand" )`"

for f in "${myArray[@]}"
do
   echo "Element: $f"
done

खराब चरित्र मौजूद होने पर भी यह दृष्टिकोण काम करता है, और किसी भी इनपुट को बैश ऐरे में बदलने का एक सामान्य तरीका है। नुकसान यह है कि यदि इनपुट लंबा है तो आप बैश की कमांड लाइन की सीमा को पार कर सकते हैं, या बड़ी मात्रा में मेमोरी का उपयोग कर सकते हैं।

वे दृष्टिकोण जहां लूप अंततः सूची में काम कर रहा है, वहां भी इस सूची में नुकसान है कि स्टड पढ़ने में आसानी होती है (जैसे इनपुट के लिए उपयोगकर्ता से पूछना), और लूप एक नई प्रक्रिया है, इसलिए आप सोच रहे होंगे कि चर क्यों लूप खत्म होने के बाद आप लूप के अंदर सेट नहीं होते हैं।

मुझे IFS की स्थापना भी नापसंद है, यह अन्य कोड को गड़बड़ कर सकता है।


यदि आप IFS='' readएक ही लाइन पर उपयोग करते हैं , तो IFS सेटिंग केवल रीड कमांड के लिए मौजूद है, और इससे बचती नहीं है। इस तरह से IFS की स्थापना को नापसंद करने का कोई कारण नहीं है।
चार्ल्स डफी

1

वैसे, मुझे बहुत से जटिल उत्तर दिखाई देते हैं। मैं खोज उपयोगिता के आउटपुट को पास नहीं करना चाहता हूं या लूप लिखना नहीं चाहता हूं, क्योंकि इसके लिए "निष्पादित" विकल्प ढूंढें।

मेरी समस्या यह थी कि मैं सभी फ़ाइलों को dbf एक्सटेंशन के साथ चालू फ़ोल्डर में ले जाना चाहता था और उनमें से कुछ में सफेद स्थान था।

मैंने इससे निपट लिया:

 find . -name \*.dbf -print0 -exec mv '{}'  . ';'

मेरे लिए बहुत सरल लगता है


0

बस पता चला कि मेरे सवाल और तुम्हारे बीच कुछ समानताएँ हैं । यदि आप आदेशों में तर्क पारित करना चाहते हैं, तो निश्चित रूप से

test.sh "Cherry Hill" "New York City"

आदेश में उन्हें मुद्रित करने के लिए

for SOME_ARG in "$@"
do
    echo "$SOME_ARG";
done;

ध्यान दें $ @ डबल कोट्स से घिरा हुआ है, यहाँ कुछ नोट्स हैं


0

मुझे क्रमिक रूप से कई निर्देशिकाओं या फ़ाइलों को एक निश्चित फ़ोल्डर से संपीड़ित करने के लिए समान अवधारणा की आवश्यकता थी। मैंने ls से सूची को पार्स करने और नाम में रिक्त स्थान की समस्या से बचने के लिए awk का उपयोग करके हल किया है।

source="/xxx/xxx"
dest="/yyy/yyy"

n_max=`ls . | wc -l`

echo "Loop over items..."
i=1
while [ $i -le $n_max ];do
item=`ls . | awk 'NR=='$i'' `
echo "File selected for compression: $item"
tar -cvzf $dest/"$item".tar.gz "$item"
i=$(( i + 1 ))
done
echo "Done!!!"

तुम क्या सोचते हो?


मुझे लगता है कि यह सही ढंग से काम नहीं करेगा अगर फाइलनेम में नई कहानियाँ हों। शायद आपको इसे आजमाना चाहिए।
user000001


-3

मेरे लिए यह काम करता है, और यह बहुत "साफ" है:

for f in "$(find ./test -type d)" ; do
  echo "$f"
done

4
लेकिन यह बदतर है। खोज के चारों ओर दोहरे उद्धरण सभी पथ नामों को एक स्ट्रिंग के रूप में संक्षिप्त करने का कारण बनते हैं। समस्या को देखने के लिए प्रतिध्वनि को एक ls में बदलें ।
NVRAM

-4

बस एक साधारण संस्करण समस्या थी ... टाइप की फ़ाइलें कन्वर्ट .flv .mp3 (yawn) के लिए।

for file in read `find . *.flv`; do ffmpeg -i ${file} -acodec copy ${file}.mp3;done

पुनरावर्ती सभी Macintosh उपयोगकर्ता फ़्लैश फ़ाइलों को ढूंढें और उन्हें ऑडियो (प्रतिलिपि, कोई ट्रांसकोड) में बदल दें ... यह ऊपर के समय की तरह है, यह ध्यान देने के बजाय कि केवल 'फ़ाइल के लिए' पढ़ने से बच जाएगा।


2
इस सूची में एक और शब्द है readजिसके बाद inआप इससे अधिक परेशान हो रहे हैं। आपने जो पोस्ट किया है वह पूछने वाले का थोड़ा टूटा हुआ संस्करण है, जो काम नहीं करता है। आप कुछ अलग पोस्ट करने का इरादा कर सकते हैं, लेकिन यह शायद वैसे भी यहां अन्य उत्तरों द्वारा कवर किया गया है।
गिलेस एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.