Changing file extensions with sed [duplicate]

2019-07-17 04:43发布

This question already has an answer here:

If the arguments are files, I want to change their extensions to .file.

That's what I got:

#!/bin/bash

while [ $# -gt 0 ]
do
    if [ -f $1 ]
    then
       sed -i -e "s/\(.*\)\(\.\)\(.*\)/\1\2file" $1

    fi
    shift
done

The script is running, but it doesn't do anything. Another problem is that file hasn't any extension, my sed command will not work, right? Please help.

2条回答
狗以群分
2楼-- · 2019-07-17 05:27

Using a shell function to wrap a sed evaluate (e) command:

mvext () 
{ 
    ext="$1";
    while shift && [ "$1" ]; do
        sed 's/.*/mv -iv "&" "&/
             s/\(.*\)\.[^.]*$/\1/
             s/.*/&\.'"${ext}"'"/e' <<< "$1";
    done
}

Tests, given files bah and boo, and the extension should be .file, which is then changed to .buzz:

 mvext file bah boo
 mvext buzz b*.file

Output:

'bah' -> 'bah.file'
'boo' -> 'boo.file'
'bah.file' -> 'bah.buzz'
'boo.file' -> 'boo.buzz'

How it works:

  1. The first arg is the file extension, which is stored in $ext.
  2. The while loop parses each file name separately, since a name might include escaped spaces and whatnot. If the filenames were certain to have not such escaped spaces, the while loop could probably be avoided.
  3. sed reads standard input, provided by a bash here string <<< "$1".
  4. The sed code changes each name foo.bar (or even just plain foo) to the string "mv -iv foo.bar foo.file" then runs that string with the evaluate command. The -iv options show what's been moved and prompts if an existing file might be overwritten.
查看更多
祖国的老花朵
3楼-- · 2019-07-17 05:28

sed is for manipulating the contents of files, not the filename itself.

Option 1, taken from this answer by John Smith:

filename="file.ext1"
mv "${filename}" "${filename/%ext1/ext2}"

Option 2, taken from this answer by chooban:

rename 's/\.ext/\.newext/' ./*.ext

Option 3, taken from this answer by David W.:

$ find . -name "*.ext1" -print0 | while read -d $'\0' file
do
   mv $file "${file%.*}.ext2"
done

and more is here.

UPDATE : (in comment asked what % and {} doing?)

"${variable}othter_chars" > if you want expand a variable in string you can use it. and %.* in {} means take the value of variable strip off the pattern .* from the tail of the value for example if your variable be filename.txt "${variable%.*} return just filename.

查看更多
登录 后发表回答