2010-11-22 88 views
1

编辑:好吧,对不起,我应该指定我在Windows上,并使用基于bash 1.14.2的win-bash以及gnuwin32工具。这意味着所有发布的解决方案都不起作用。它不包含许多高级功能。然而,我终于明白了。这是一个丑陋的脚本,但它的作品。递归BASH重命名

#/bin/bash 
function readdir 
{ 
    cd "$1" 
    for infile in * 
    do 
    if [ -d "$infile" ]; then 
     readdir "$infile" 
    else 
     renamer "$infile" 
    fi 
    done 
    cd .. 
} 

function renamer 
{ 
    #replace " - " with a single underscore. 
    NEWFILE1=`echo "$1" | sed 's/\s-\s/_/g'` 
    #replace spaces with underscores 
    NEWFILE2=`echo "$NEWFILE1" | sed 's/\s/_/g'` 
    #replace "-" dashes with underscores. 
    NEWFILE3=`echo "$NEWFILE2" | sed 's/-/_/g'` 
    #remove exclamation points 
    NEWFILE4=`echo "$NEWFILE3" | sed 's/!//g'` 
    #remove commas 
    NEWFILE5=`echo "$NEWFILE4" | sed 's/,//g'` 
    #remove single quotes 
    NEWFILE6=`echo "$NEWFILE5" | sed "s/'//g"` 
    #replace & with _and_ 
    NEWFILE7=`echo "$NEWFILE6" | sed "s/&/_and_/g"` 
    #remove single quotes 
    NEWFILE8=`echo "$NEWFILE7" | sed "s/’//g"` 

    mv "$1" "$NEWFILE8" 
} 

for infile in * 
do 
    if [ -d "$infile" ]; then 
    readdir "$infile" 
    else 
    renamer "$infile" 
    fi 
done 

ls 

我想创建一个bash脚本来递归通过一个目录和重命名文件,以删除空格,破折号和其他字符。我已经得到了我所需要的脚本,除了它的递归部分。我仍然对此感到陌生,所以它不像应该那样高效,但它很有效。任何人都知道如何做这个递归?

#/bin/bash 
for infile in *.*; 
do 
#replace " - " with a single underscore. 
NEWFILE1=`echo $infile | sed 's/\s-\s/_/g'`; 
#replace spaces with underscores 
NEWFILE2=`echo $NEWFILE1 | sed 's/\s/_/g'`; 
#replace "-" dashes with underscores. 
NEWFILE3=`echo $NEWFILE2 | sed 's/-/_/g'`; 
#remove exclamation points 
NEWFILE4=`echo $NEWFILE3 | sed 's/!//g'`; 
#remove commas 
NEWFILE5=`echo $NEWFILE4 | sed 's/,//g'`; 
mv "$infile" "$NEWFILE5"; 
done; 
+0

我觉得它比计算器更多的超级用户,但如果它只是为了解决一个特定的Linux操作系统中的东西我会使用查找和重命名。 – Fredrik 2010-11-22 20:49:49

+0

如果您使用`*。*`,则不匹配不包含“`。”“的文件。在Bash中,仅仅使用`*` – 2010-11-22 21:27:56

回答

2

所有这些分号是多余的,没有理由使用所有这些变量。如果您想要将sed命令放在单独的行中并散布详细的注释,您仍然可以执行此操作。

#/bin/bash 
find . | while read -r file 
do 
    newfile=$(echo "$file" | sed ' 
     #replace " - " with a single underscore. 
     s/\s-\s/_/g 
     #replace spaces with underscores 
     s/\s/_/g 
     #replace "-" dashes with underscores. 
     s/-/_/g 
     #remove exclamation points 
     s/!//g 
     #remove commas 
     s/,//g') 
    mv "$infile" "$newfile" 
done 

这是更短:

#/bin/bash 
find . | while read -r file 
do 
    # replace " - " or space or dash with underscores 
    # remove exclamation points and commas 
    newfile=$(echo "$file" | sed 's/\s-\s/_/g; s/\s/_/g; s/-/_/g; s/!//g; s/,//g') 
    mv "$infile" "$newfile" 
done 

时间更短:

#/bin/bash 
find . | while read -r file 
do 
    # replace " - " or space or dash with underscores 
    # remove exclamation points and commas 
    newfile=$(echo "$file" | sed 's/\s-\s/_/g; s/[-\s]/_/g; s/[!,]//g') 
    mv "$infile" "$newfile" 
done 
0

在bash 4中,设置globstar选项允许递归通配。

shopt -s globstar 
for infile in ** 
... 

否则,请使用find

while read infile 
do 
... 
done < <(find ...) 

find ... -exec ... 
+0

更加地道,好吧,看起来我还有很多东西需要学习,因为你现在让我感到困惑。我实际上是在Windows上使用bash,使用gnuwin32工具和win-bash,这显然是基于bash 1.14.2。 到目前为止,感谢您的帮助,我会尝试看看能否从这里弄清楚,但如果您可以完成脚本以供我查看为例,则将不胜感激。 – Ryan 2010-11-22 20:53:03

3

find是能够显示在一个文件系统层次的所有元素的命令。您可以使用它来在每个找到的文件上执行命令,或者将结果传送到将处理执行部分的xargs

请注意,for infile in *.*不适用于包含空格的文件。检查-print0选项find,加上-0选项xargs

0

我以前用'find'来定位文件,然后让它执行另一个应用程序。 见'-exec'

0
rename 's/pattern/replacement/' glob_pattern 
+0

例如`重命名's/\ s + // g''文件名与Whitespace'`将它重命名为'FileNameWithWhitespace' – 2010-11-22 21:30:32