重命名文件,但将它们保存在当前的子目录中

时间:2013-12-05 20:49:56

标签: bash awk mv renaming pwd

我有一个脚本根据标签中的信息重命名html文件。此脚本遍历当前目录和所有子目录,并以递归方式执行此重命名。但是,重命名后,它会将它们移动到我正在执行我的shell脚本的当前工作目录中。如何确保文件保留在子目录中,并且不会移动到工作目录?

以下是我的工作内容:

#!/usr/bin/env bash
for f in `find . -type f | grep \.htm`
   do
   title=$( awk 'BEGIN{IGNORECASE=1;FS="<title>|</title>";RS=EOF} {print $2}' "$f" )
   mv  ./"$f" "${title//[ ]/-}".htm
done

3 个答案:

答案 0 :(得分:2)

永远不要使用此构造:

for f in `find . -type f | grep \.htm`

因为包含空格的文件名的循环失败而且grep是不必要的,因为find具有-name选项。请改用:

find . -type f -name '*\.htm.*' -print |
while IFS= read -r f

此:

awk 'BEGIN{IGNORECASE=1;FS="<title>|</title>";RS=EOF}

可以简化并澄清为:

awk 'BEGIN{IGNORECASE=1;FS="</?title>";RS=""}

请注意,使用EOF会产生误导,因为EOF只是一个未定义的变量,因此包含一个空字符串(因此您的第一个记录将一直到第一个空行,直到文件结尾)。您可以使用RS=bubba并获得相同的效果,但只需将RS设置为空字符串就更清楚了。不是说这应该是你应该做的,而是更清楚地实现你正在做的事情。

最后把它们放在一起这样的东西对你有用:

find . -type f -name '*\.htm.*' -print |
while IFS= read -r f
do
    title=$( awk 'BEGIN{IGNORECASE=1;FS="</?title>";RS=""} {print $2}' "$f"
    mv -- "$f" $(dirname "$f")/"${title//[ ]/-}".htm
done

答案 1 :(得分:1)

尝试:

mv  ./"$f" "$(dirname "$f")/${title//[ ]/-}".htm

请注意,for f in \ find ...'会在任何带有空格或CR的文件名上失败。您可以使用以下行来避免这种情况:

find . -type f -name '*.htm' -type f -exec myrename.sh {} \;

其中重命名代码位于名为myrename.sh的脚本中。

答案 2 :(得分:1)

shopt -s globstar nullglob
for f in **/*.htm
do
   title=$( awk 'BEGIN{IGNORECASE=1;FS="<title>|</title>";RS=EOF} {print $2}' "$f" )
   mv  "$f" "$(dirname "$f")/${title//[ ]/-}".htm
done