Bash rename extension recursive

后端 未结 6 1548
-上瘾入骨i
-上瘾入骨i 2020-12-29 09:32

I know there are a lot of things like this around, but either they don\'t work recursively or they are huge.

This is what I got:

find . -name \"*.so\         


        
相关标签:
6条回答
  • 2020-12-29 09:57

    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).

    0 讨论(0)
  • 2020-12-29 09:57

    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.
    0 讨论(0)
  • 2020-12-29 09:57

    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 {} {}
    

    0 讨论(0)
  • 2020-12-29 10:15
    for X in `find . -name "*.so"` 
    do
     mv $X ${X/.so/.dylib}
    done
    
    0 讨论(0)
  • 2020-12-29 10:15

    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 "."
    
    0 讨论(0)
  • 2020-12-29 10:16

    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
    
    0 讨论(0)
提交回复
热议问题