Solved Looping through subdirectories

Greetings all,

in an attempt to learn scripting, I decided that a good task would be to replace empty spaces in directory a folder names with underscores. So I am trying to find all sub-directories and files in the current directory. I am using the tutorial at www.shellscript.com, which has an example under Loops for2.sh, which allegedly loops through all files in a directory. Thus:
Code:
 # Find directories and files with spaces, replace with deesired character
#!/bin/sh
# Set protection
set -Cefu

# Define variables
SEARCH_DIRECTORY="/some_directory"

cd $SEARCH_DIRECTORY

# find and rename directories and files
for idx in *
do
    if [ -d "$idx" ]
    then
        echo "Process directory "$idx""
    else
        echo "Process files in directory "$idx""
    fi
done

But it does not work. Any ideas?

Also, is there any other good tutorial?

Kindest regards,

M
 
One thing that jumps out at me, that might just be a typo--err two things, all in the SEARCH_DIRECTORY variable. I'm assuming you mistyped when you posted it here, but you have
Code:
SERACH DIRECTORY
with search spelled wrong and no underscore between the misspelled search and the word directory.

However IF that's not a typo, it's definitely part of why it's not working.
Also, are you getting any errors when you run the script. One way to troubleshoot is do
sh -x for2.sh
 
Hi Scottro,

thank you for the reply. Yes, it was a misspelling, I found that by running it through www.shellchedker.net. It no longer reports any formal errors, but the script still does not work.

I will try your suggested command. No, no errors, it just seems to not loop, stops at the root directory.

Kindest regards,

M

P.S. I have corrected the code, so other people are not mislead.

M
 
I thought this job must be possible in a oneliner, and sure enough it is, but now as I see the result, I wouldn't recommend that any more :D
Still leaving it here for amusement 🤡
Code:
find /tmp -depth -name "* *" -execdir sh -c mv\ \"\{\}\"\ \$\(echo\ \{\}\|tr\ \"\ \"\ _\) \;
(Escape the shell of doom…)
 
Hi Zirias,

thank you for your suggestion.

I have found several solutions using find, but several of such posts had warning against doing it this way, without any explanations why. Further, this is unacceptable, what is there is already a file with the same name as the de-spaced name.

Furthermore, my intention was to use the problem as exercise to learn scripting. But, given the lack of debugging tools and non-working examples, I wonder is my time would not better spend on learning a real language, perl, python.

Kindest regards,

M
 
It's not a suggestion, well, not any more. I just couldn't hide the awesome piece of escape-hell I accidentally created :D

For some serious answer:
  • Your #1 debugging tool is echo.
  • Your error is in the set command, which you probably blindly copied from somewhere. Have a look at sh(1) to find what set -f will do:
    Code:
         -f noglob
                 Disable pathname expansion.
    This is exactly what you attempt to use with the * in your for
  • In general, I think all these flags are questionable. Read the manpage and understand what they do…
 
Hi Zirias,

yes that was it. I reread the settings and disabled the f, and it worked.

Kindest regards.

M
 
Hi Zirias,

I did read about them, but I completely forgot. When i commented the settings, I recalled what the -f option meant.

Kindest regards,

M
 
Personally, I'd go with:

pkg install rename
cd $whereever
rename -t -R -v -s/" "/_/gi *

-t test mode, list what would be done but don't do it.
-R recurse down sub-dirs
-v verbose
-s substitute " " with _
g global, ie all occurrences in file or dir name
i ignore case (not actually relevant here)
* act on all files/dirs found

I find it very useful for batch/bulk renaming, particularly as it supports regular and extended regular expression.

PS, I think it installs the binary as renamex, NOT rename these days.
 
Back
Top