简体   繁体   中英

How to remove leading or trailing spaces in files, directories, and subdirectories using bash script?

On mac OS X, how to get a bash script working to change over a 1,000 files and sub-directories and many sub-sub-directories in the current working directory.

Tried using a script from Find and replace filename recursively in a directory answer, however that doesn't take into account filenames or directories that have leading or trailing spaces, as the spaces need to be escaped. However as you can see the below line the path is also escaped and the script doesn't work.

find . -name '* ' -type d -exec bash -c 'echo mv "$1"/ \\""${1/ /}\\""' -- {} \\;

(Note: Yes I'm using echo to see the commands.)

The bash script needs to trim leading and trailing spaces of both files and directories. By "trim" I mean remove leading and trailing spaces and leaving the spaces in between words alone.

Example Structure:


./
./ Leading Space/
./ Leading Space/ Text File With Leading Space.txt
./Trailing Space /
./Trailing Space / Multiple Trailing and Leading Spaces  /
./Trailing Space / Multiple Trailing and Leading Spaces  /  Trailing and Leading Spaces Text File  .txt

Note: The answer will need to work on any default mac OS X. I will not accept an answer that uses third party applications or plugins, including Mac Automator and perl rename .

To remove trailing blanks from both directories and files:

find . -depth -name '* ' -execdir bash -c 'mv "$1" "${1%"${1##*[^[:space:]]}"}"' Move {} \;

To remove leading whitespace:

find . -depth -name ' *' -execdir bash -c 'f=${1#./}; mv "./$f" "./${f#"${f%%[![:space:]]*}"}"' Move {} \;

Notes:

  1. So that directories are not renamed while find is searching inside them, we need to specify -depth .

  2. The shell expansion ${1%"${1##*[^[:space:]]}"} removes trailing white space while ${f#"${f%%[![:space:]]*}"} removes leading white space.

  3. The first non-option argument to bash -c is assigned to $0 and is used as the program name in error messages should any errors occur. It is good practice to use a descriptive name here, like Move as shown above.

The above was tested under Linux.

You can use a simple for loop and replace the space by an underline with something like this:

for FILE in *\ *
do
    mv "$FILE" "${FILE// /_}"
done

For multiple sub-directories, you can use something like this:

for FILE in ./* */* */* *; do  mv "$FILE" "${FILE// /_}"; done 2>/dev/null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM