bash脚本在子文件夹中的多个文件重命名为自己的文件夹名称

问题描述:

我有以下文件结构:bash脚本在子文件夹中的多个文件重命名为自己的文件夹名称

Applications/Snowflake/applications/Salford_100/wrongname_120.nui; wrongname_200_d.nui 
Applications/Snowflake/applications/Salford_900/wrongname_120.nui; wrongname_200_d.nui 
Applications/Snowflake/applications/Salford_122/wrongname_120.nui; wrongname_200_d.nui 

而且我想给FLES重命名为目录他们在相同的名称,但最后带有“_d”的文件应保留最后2个字符。文件模式将始终为“salford_xxx”,其中xxx始终为3位数字。因此,生成的文件将是:

Applications/Snowflake/applications/Salford_100/Salford_100.nui; Salford_100_d.nui 
Applications/Snowflake/applications/Salford_900/Salford_900.nui; Salford_900_d.nui 
Applications/Snowflake/applications/Salford_122/Salford_122.nui; Salford_122_d.nui 

该脚本会从不同的位置

Applications/Snowflake/Table-updater 

来看,我想这将需要一个for循环和sed的正则表达式,但是我任何建议开放。 (谢谢@ ghoti的建议) 我试过了,目前还没有用“_d”来解释文件,而我只是将一个文件正确地重命名了。一些帮助将不胜感激。

cd /Applications/snowflake/table-updater/Testing/applications/salford_* 

dcomp="$(basename "$(pwd)")" 
for file in *; do 
ext="${file##*.}" 
mv -v "$file" "$dcomp.$ext" 

done 

伊夫现在更新以下@varun意见(谢谢),它现在也通过搜索包含在名称索尔福德的父目录中的所有文件,列缺父名的脚本。请参考下面

#!/bin/sh 
# 
# RenameToDirName2.sh 
# 
set -e 

cd /Applications/snowflake/table-updater/Testing/Applications/ 

find salford* -maxdepth 1 -type d \(! -name . \) -exec sh -c '(cd {} && 
    (
     dcomp="$(basename "$(pwd)")" 
     for file in *; 
     do ext="${file#*.}" 
      zz=$(echo $file|grep _d) 
     if [ -z $zz ] 
     then 
      mv -v "$file" "$dcomp.$ext" 
     else 
      mv -v "$file" "${dcomp}_d.$ext" 
    fi 
done 
) 
)' ';' 

的事情是,我刚刚意识到,在这些索尔福德子目录有与我不想重新命名不同的扩展名的其他文件。香港专业教育学院试图在别人把if语句来规定* .Nui文件只,打电话给我的$ DCOMP变量,这样

else 
    if file in $dcomp/*.nui 
    then 
    #continue... 

但我得到的错误。这应该在我的脚本中去哪里,我也有这个循环的正确语法?你能帮我吗?

+1

所以文件名实际上是'wrongname_120.nui; wrongname_200_d.nui',还是这两个单独的文件在同一个目录中? – Will

+0

2个独立的文件在同一目录中。对任何混淆抱歉。 – Eggfoot

+0

你有什么尝试?我们大多数人都非常乐意帮助您学习如何改进技巧,但不太愿意担任无偿代码猴。 – ghoti

@ eggfoot,我已经修改我的脚本,它将查看文件夹应用程序中的所有目录,并查找其中包含Salford的文件夹。 所以,你可以打电话给我这样的脚本

./rename.sh /家/用户名/应用/雪花E /应用

#!/bin/bash 
# set -x 
path=$1 
dir_list=$(find $path/ -type d) 
for index_dir in $dir_list 
do 
    aa=$(echo $index_dir|grep Salford) 
    if [ ! -z $aa ] 
    then 
      files_list=$(find $index_dir/ -type f) 
      for index in $files_list 
      do 
        xx=$(basename $index) 
        z=$(echo $xx|grep '_d') 
        if [ -z $z ] 
        then 
          result=$(echo $index | sed 's/\/\(.*\)\/\(.*\)\/\(.*\)\(\..*$\)/\/\1\/\2\/\2\4/') 
          mv "$index" "$result" 
        else 
          result=$(echo $index | sed 's/\/\(.*\)\/\(.*\)\/\(.*\)_d\(\..*$\)/\/\1\/\2\/\2_d\4/') 
          mv "$index" "$result" 
        fi 
      done 
    fi 
    done 

关于SED,它使用的SED s命令和替代文件名称与目录名称,保持原样。

关于您的脚本,您需要使用grep命令来查找具有_d的文件,并且您可以使用参数替换来更改带有_d的文件的mv,而不带_d的文件。

dcomp="$(basename "$(pwd)")" 
    for file in *; do 
    ext="${file##*.}" 
    zz=$(echo $file|grep _d) 
    if [ -z $zz ] 
    then 
    mv -v "$file" "$dcomp.$ext" 
    else 
    mv -v "$file" "${dcomp}_d.$ext" 
    fi 
    done 
+0

感谢这个@Varun,你能分解一下sed正则表达式中发生了什么?对不起,我仍然在学习这一切。此外,Salford_xxx文件夹名称后的3位数字将随机生成,因此脚本的参数可能为: ./rename.sh/home/username/Applications/Snowflake e/applications/Salford_ *? – Eggfoot

你可以写:

(
    cd ../applications/ && \ 
    for name in Salford_[0-9][0-9][0-9] ; do 
     mv "$name"/*_[0-9][0-9][0-9].nui "$name/$name.nui" 
     mv "$name"/*_[0-9][0-9][0-9]_d.nui "$name/${name}_d.nui" 
    done 
) 

(注:该(...)是一个子shell,限制目录的更改和name变量的范围)

+0

这似乎将范围[0-9] [0-9] [0-9]作为实际文件名并标记错误“No such file or directory”。 – Eggfoot

+0

@Eggfoot:由于我无法访问您的框,因此我必须使用您在问题中提供的信息。只要你的盒子上的情况与问题中的情况不完全匹配,你可能需要相应地调整答案。 – ruakh