同时循环文件名并删除空格

时间:2014-10-07 02:37:17

标签: linux bash shell unix

我目前正在处理格式化文件名。下面我有一个while循环,它运行文件名并用_替换空格,并保留连字符后的任何内容。现在问题是循环遍历find命令的结果以格式化名称。在脚本中运行时,输出如下:

find: paths must precede expression: rename
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

rename.sh

while read -r file
do
   new_file=$(echo "$file" | sed -re 's/^([^-]*)-\s*([^\.]*)/\L\1\E-\2/' -e 's/ /_/g' -e 's/_-/-

/g')
       echo "mv '$file' '$new_file'"
  done < <(find ./ -type f rename)

之前的文件名:

'./My File - KeEp.txt'

文件名后:

'./my_file-KeEp.txt'

2 个答案:

答案 0 :(得分:2)

您打算renamefind ./ -type f rename做什么?

find正如错误消息告诉您的那样,将其解释为路径(搜索),然后告诉您不允许在参数之后添加路径。

话虽如此,正如@Beta在他的评论中指出的那样,在这里使用while循环是不必要的(而且是脆弱的)。

请改为尝试:

find ./ -type f -exec bash -c 'echo "mv \"$1\" \"$(echo "$1" | sed -re '\''s/^([^-]*)-\s*([^\.]*)/\L\1\E-\2/'\'' -e '\''s/ /_/g'\'' -e '\''s/_-/-/g'\'')\""' - {} \;

或者这实际上是这样做的:

find ./ -type f -exec bash -c 'mv "$1" "$(echo "$1" | sed -re '\''s/^([^-]*)-\s*([^\.]*)/\L\1\E-\2/'\'' -e '\''s/ /_/g'\'' -e '\''s/_-/-/g'\'')"' - {} \;

稍微解释一下:

  • '\''位是你如何在单引号字符串中转义单引号(你结束字符串,转义单引号并再次启动字符串)。
  • -中的- {}用于填充$0参数,该参数是使用bash和其他参数运行时-c的第一个参数。 (如果不这样,脚本需要使用$0而不是$1来访问文件名。)

哦,你的原始脚本在你想要扩展的变量周围使用单引号,当你从echo命令中取出双引号时,它就不起作用了。

答案 1 :(得分:1)

我认为你的主要错误是&#34;重命名&#34; find命令的参数,我不明白为什么你把它放在那里。还有一些事情你也可以改进,例如不尝试重命名后面有相同名称的文件,而不是&#34; ./"你可以简单地写'#34;。&#34;。 另请注意,您的脚本不会在连字符之后保留任何内容&#34;因为即使在你的示例文件名中,它也会改变空格。

我仍然会使用while循环,因为每次重命名产生bash + sed都可以通过这种方式消除。我使用find的-name参数只处理包含连字符的文件名。

这样的事情:

while read -r file; do
    x="${file%%-*}" # before first hyphen
    y="${file#*-}" # after first hyphen
    x="${x,,[A-Z]}" # make it lowercase
    x="${x// /_}" # change all spaces to underscores
    new_file="${x}-${y}"
    if [ "$file" != "$new_file" ]; then
        echo mv "$file" "$new_file"
    fi
done < <(find . -type f -name '*-*')