user2420889
user2420889

Reputation: 1

Bash script to change file names recursively

I have a script for changing file names of mht files but it does not traverse through dirs and sub dirs. I asked a question on a local forum and I got an answer that this is a solution:

find . -type f -name "*.mhtml" -o  -type f -name "*.mht" | xargs -I item sh -c '{ echo item; echo item | sed "s/[:?|]//g"; }' | xargs -n2 mv

But it generates an error. With some of my experimenting it turns out that sh -c breaks file names with space and that this generates an error. How can I fix this?

#!/bin/bash
# renames.sh
# basic file renamer
for i in  . *.mht
do
j=`echo $i | sed 's/|/ /g' | sed 's/:/ /g' | sed 's/?//g' | sed 's/"//g'`
    mv "$i" "$j"
    done

Upvotes: 0

Views: 1725

Answers (2)

nosid
nosid

Reputation: 50034

#! /bin/bash
find . -type f \( -name "*.mhtml" -o -name ".mht" \) -print0 |
while IFS= read -r -d '' source; do
    target="${source//[:?|]/}"
    [ "X$source" != "X$target" ] &&
    mv -nv "$source" "$target"
done

Update: Do the rename according to the original question, and added support for .mht.

Upvotes: 2

Lynch
Lynch

Reputation: 9474

Use rename. With rename you can specify a renaming pattern:

find . -type f \( -name "*.mhtml" -o -name "*.mht" \) -print0 | xargs -0 -I'{}' rename  's/[:?|]//g' "{}"

This way you can properly handle names with spaces. xargs will replace {} with every names of file provided by the find command. Also note the use of -print0 and -0. This use a \0 as a separator so its avoid problems dealing with filnames containing \n (newline).

The -o was not working the way it was intended to. you must use parenthesis to group conditions.

You may also consider using -iname instead of -name if you deal with file ending with ".mHtml".

Upvotes: 1

Related Questions