递归BASH重命名

递归BASH重命名,bash,Bash,编辑:好的,很抱歉,我应该指定我在Windows上,使用win bash,它基于bash 1.14.2,以及gnuwin32工具。这意味着不幸的是,所有发布的解决方案都没有帮助。它不包含许多高级功能。不过,我终于明白了。这是一个丑陋的剧本,但它是有效的 #/bin/bash function readdir { cd "$1" for infile in * do if [ -d "$infile" ]; then readdir "$infile" el

编辑:好的,很抱歉,我应该指定我在Windows上,使用win bash,它基于bash 1.14.2,以及gnuwin32工具。这意味着不幸的是,所有发布的解决方案都没有帮助。它不包含许多高级功能。不过,我终于明白了。这是一个丑陋的剧本,但它是有效的

#/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;

在bash4中,设置
globstar
选项允许递归全局搜索

shopt -s globstar
for infile in **
 ...
否则,请使用
查找

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

在bash4中,设置
globstar
选项允许递归全局搜索

shopt -s globstar
for infile in **
 ...
否则,请使用
查找

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

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


请注意*.
中的infle的
不适用于包含空格的文件。检查
find
-print0
选项,与
xargs
-0
选项相结合,该命令能够显示文件系统层次结构中的所有元素。您可以使用它对找到的每个文件执行命令,或将结果传送到将处理执行部分的
xargs


请注意*.
中的infle的
不适用于包含空格的文件。检查
find
-print0
选项,与
xargs
-0
选项相结合,我过去使用“find”定位文件,然后让它执行另一个应用程序。
请参见

我过去曾使用“查找”来定位文件,然后让它执行另一个应用程序。
请参见

所有这些分号都是多余的,没有理由使用所有这些变量。如果您想将
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

所有这些分号都是多余的,没有理由使用所有这些变量。如果您想将
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

我认为它比stackoverflow更为超级用户,但如果它只是为了修复特定linux设备上的某些问题,我会使用查找和重命名。如果使用
*.
,您将无法匹配不包含“
”的文件。在Bash中,只使用
*
更为惯用,我认为它比stackoverflow更为超级用户,但如果它只是为了修复特定linux设备上的某些问题,我会使用查找和重命名。如果使用
*.
则不会匹配不包含“
”的文件。在Bash中,只使用
*
更为惯用。好吧,看来我还有很多东西要学,因为你现在把我弄糊涂了。我实际上是在Windows上使用bash,使用gnuwin32工具和win bash,后者显然是基于bash 1.14.2的。谢谢你到目前为止的帮助,我会试着看看我是否能从这里找到答案,但是如果你能完成脚本让我看作为一个例子,我将不胜感激。好的,看起来我还有很多东西要学,因为你现在让我困惑了。我实际上是在Windows上使用bash,使用gnuwin32工具和win bash,后者显然是基于bash 1.14.2的。谢谢你到目前为止的帮助,我会试着看看我是否能从这里弄明白,但是如果你能完成这个脚本让我看作为一个例子,我将不胜感激
rename's/\s+//g''File Name With Whitespace'
将其重命名为
filename With Whitespace
例如
rename's/\s+//g''File Name With Whitespace'
将其重命名为
filename With Whitespace
不幸的是,您的解决方案不起作用:(我正在使用带有gnuwin32工具的win bash,我得到了“选项在此NT BASH版本上不可用[sic]"在查找行。win bash基于bash 1.14.2,很遗憾,它不支持更新的功能。不过,谢谢。我已将您的答案标记为其他正在寻找解决方案的人的答案,他们使用的是实际的*nix系统。我确信它在他们身上可以工作。@Ryan:您可能可以省略
-r
。这只是用来处理反斜杠,而不需要输入将它们解释为逃逸。不。我不确定它到底不支持什么,但我怀疑它是find输出的管道。不管怎样,我现在已经通过一些难看的脚本解决了它:p。谢谢。不幸的是,对我来说,你的解决方案不起作用:(我正在使用winbash和gnuwin32工具,我得到了“option not availible[sic]在此NT BASH版本上“在查找行。win bash基于bash 1.14.2,很遗憾,它不支持更新的功能。不过,谢谢。我已将您的答案标记为其他正在寻找解决方案的人的答案,他们使用的是实际的*nix系统。我确信它在他们身上可以工作。@Ryan:您可能可以省略
-r
。这只是用来处理反斜杠,而不需要输入将它们解释为逃避。不。我不确定它到底不支持什么,但我怀疑它是find输出的管道。不管怎样,我现在已经通过一些难看的脚本解决了它:p。不过谢谢。