0

I can't find a way to put an entry in read that contains spaces? I want to put directories in the "Enter directory to be cleaned:" read. I think it is reading the spaces as separate variables. Input would be something like /home/user/apple sauce The "cleaning" is just removing special characters from filenames.

#!/bin/bash
read -p "Enter directory to be cleaned: " directory
echo "Current Directory Structure"
/usr/bin/ls -la $directory 

read input
    if [ "$input" == "y" ]
    then
    echo "Cleaning files..." 
        for file in $directory; do mv $file $(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g'); done &
else    
    stop
fi

Another issue I am facing is the cleanup is repeating the entire directory when it creates the new filename. If I run that for file in *; do mv "$file" $(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g'); done & command in the directory itself, it just creates the new filename. If I specify the directory it writes out the whole directory:

++ sed -e 's/[^A-Za-z0-9._-]/_/g'
++ echo '/home/apples/scratch/test1/test:something?'
+ mv '/home/apples/scratch/test1/test:something?' _home_apples_scratch_test1_test_something_

I want it to just change the filename but having issues. Any help is thankful.

saleetzo
  • 115
  • 7
  • 4
    You mostly need to double-quote variables; [shellcheck.net](https://www.shellcheck.net) will point out where. Also, `for file in $directory` doesn't list files in the directory, use `for file in "$directory"/*`. You'll also have trouble with the `sed` pattern trying to replace characters in both the filename *and* the containing directory name (that's more complicated). Oh, and use `IFS= read -r -p ...` to avoid mangling backslashes, and also spaces at the beginning/end. – Gordon Davisson Feb 05 '21 at 02:39
  • 1
    @saleetzo : Don't ask two problems in one question. Use two questions for this. – user1934428 Feb 05 '21 at 08:23
  • thank you @GordonDavisson! i also didn't konw about spellcheck.net, very cool. – saleetzo Feb 05 '21 at 20:51

1 Answers1

1

I think it is reading the spaces as separate variables

It does not, as you can easily verify with this:

read -p 'Enter string:'  x
echo "Entered: >>>$x<<<"

If you dislike quoting your variables (to avoid word splitting), you may consider switching from bash to Zsh. Where you have to write "$x" in bash, you would simply write $x in Zsh.

Hence, you would have to write

for file in "$directory"

but this would loop just one iteration, with file bound to the content of the variable directory. For looping over the entries in this directory, you would do a

for dirent in "$directory"/*
user1934428
  • 19,864
  • 7
  • 42
  • 87