Bash rename extension recursive

て烟熏妆下的殇ゞ 提交于 2019-11-30 05:03:12
aps2012

This will do everything correctly:

find -L . -type f -name "*.so" -print0 | while IFS= read -r -d '' FNAME; do
    mv -- "$FNAME" "${FNAME%.so}.dylib"
done

By correctly, we mean:

1) It will rename just the file extension (due to use of ${FNAME%.so}.dylib). All the other solutions using ${X/.so/.dylib} are incorrect as they wrongly rename the first occurrence of .so in the filename (e.g. x.so.so is renamed to x.dylib.so, or worse, ./libraries/libTemp.so-1.9.3/libTemp.so is renamed to ./libraries/libTemp.dylib-1.9.3/libTemp.so - an error).

2) It will handle spaces and any other special characters in filenames (except double quotes).

3) It will not change directories or other special files.

4) It will follow symbolic links into subdirectories and links to target files and rename the target file, not the link itself (the default behaviour of find is to process the symbolic link itself, not the file pointed to by the link).

for X in `find . -name "*.so"` 
do
 mv $X ${X/.so/.dylib}
done
mlunoe

A bash script to rename file extensions generally

  #/bin/bash
  find -L . -type f -name '*.'$1 -print0 | while IFS= read -r -d '' file; do
      echo "renaming $file to $(basename ${file%.$1}.$2)";
      mv -- "$file" "${file%.$1}.$2";
  done

Credits to aps2012.

Usage

  1. Create a file e.g. called ext-rename (no extension, so you can run it like a command) in e.g. /usr/bin (make sure /usr/bin is added to your $PATH)
  2. run ext-rename [ext1] [ext2] anywhere in terminal, where [ext1] is renaming from and [ext2] is renaming to. An example use would be: ext-rename so dylib, which will rename any file with extension .so to same name but with extension .dylib.

What is wrong is that

echo {} | sed s/.so/.dylib/
is only executed once, before the find is launched, sed is given {} on its input, which doesn't match /.so/ and is left unchanged, so your resulting command line is
find . -name "*.so" -exec mv {} {}

if you have Bash 4

#!/bin/bash

shopt -s globstar
shopt -s nullglob
for file in /path/**/*.so
do
 echo mv "$file"  "${file/%.so}.dylib"
done
Tony

He needs recursion:

#!/bin/bash

function walk_tree {
    local directory="$1"
    local i

    for i in "$directory"/*; 
        do
            if [ "$i" = . -o "$i" = .. ]; then 
                continue
            elif [ -d "$i" ]; then  
            walk_tree "$i"  
            elif [ "${i##*.}" = "so" ]; then
                echo mv $i ${i%.*}.dylib    
            else
                continue
            fi
        done    
}

walk_tree "."
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!