【问题标题】:While loop through file names and remove white spaceWhile 循环遍历文件名并删除空格
【发布时间】:2014-10-07 11:23:06
【问题描述】:

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

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

重命名.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'

【问题讨论】:

  • ... 省略了哪些内容,因为这是脚本的重要部分,因为错误是 find 抱怨它的论点。
  • 如果你使用find,你也可以给它一个action来重命名文件。这样你就可以避免整个 while do ... done &lt; (find ...) 结构。
  • @EtanReisner,那是我的错误。我更正了。
  • @Beta,好吧,我最初有一个操作确实变成了小写,删除了空格但影响了整个文件名。我只想重新格式化文件名的-

标签: linux bash shell unix


【解决方案1】:

你打算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'\'')"' - {} \;

稍微解释一下:

  • '\'' 位是在单引号字符串中转义单引号的方式(结束字符串、转义单引号并重新开始字符串)。
  • - {} 中的- 是在使用-c 和其他参数运行时填充$0 参数,这是bash 的第一个参数。 (否则,脚本将需要使用 $0 而不是 $1 来访问文件名。)

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

【讨论】:

  • 这更有意义。 +1 将所有内容集中在一个命令中。现在正在做出改变,但我一直在关注这个mv: ./Thumbs.dbâ and ./Thumbs.dbâ are the same file
  • @Code_Ed_Student 是的,任何未更改的文件都会发生这种情况。您可以将$new_file 变量重新添加到脚本中并进行比较,然后仅在它们不同时才执行mv,否则该消息是“无害的”。
【解决方案2】:

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

我仍然会使用 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 '*-*')

【讨论】:

  • 我实际上正在重新评估这个答案。它也特别希望它在- 之前和之后剥离空间。示例:test Text - new - thing.txttest_text-new-thing.txt。我想通过将其替换为 - 来避免多余的 _-
猜你喜欢
  • 2019-11-10
  • 2015-12-24
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
  • 2023-02-24
相关资源
最近更新 更多