2

我有一个脚本,可以根据标签中的信息重命名 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
4

3 回答 3

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
于 2013-12-05T21:14:55.113 回答
1

尝试:

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

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

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

其中重命名代码位于名为myrename.sh.

于 2013-12-05T21:02:02.857 回答
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
于 2013-12-05T21:02:15.893 回答