如何重命名文件名包含反斜杠?



>我得到了一个tar文件,解压缩后,有很多文件命名,例如

a
bc
def
gh

我想将它们的名字更正为子目录中的文件,例如

a
b/c
d/e/f
g/h

当变量包含反斜杠时,我遇到了一个问题,它将更改原始文件名。我想写一个脚本来重命名它们。

参数扩展是要走的路。您在bash拥有所需的一切,无需使用find等外部工具。

$ touch a\b c\d\e
$ ls -l
total 0
-rw-r--r--  1 ghoti  staff  0 11 Jun 23:13 ab
-rw-r--r--  1 ghoti  staff  0 11 Jun 23:13 cde
$ for file in *\*; do
> target="${file//\//}"; mkdir -p "${target%/*}"; mv -v "$file" "$target"; done
ab -> a/b
cde -> c/d/e

for 循环中断如下:

  • for file in *\*; do- 选择名称包含反斜杠的所有文件
  • target="${file//\//}";- 将反斜杠换成正斜杠
  • mkdir -p "${target%/*}";- 通过从$target中删除文件名来创建目标目录
  • mv -v "$file" "$target";- 将文件移动到其新主页
  • done- 结束循环。

我认为这里唯一棘手的一点是第二行:${file//\//}${var//pattern/replacement}的表达式,其中模式是转义的反斜杠(\),替换是单个正斜杠。

查看man bash并搜索"参数扩展"以了解更多信息。


或者,如果你真的想使用find,你仍然可以利用 bash 的参数扩展:

find . -name '*\*' -type f 
-exec bash -c 't="${0//\//}"; mkdir -p "${t%/*}"; mv -v "$0" "$t"' {} ;

这使用find来识别每个文件并使用-exec选项对其进行处理,该选项基本上与上面的for循环执行相同的操作。这里的一个显着区别是find将遍历子目录(受-maxdepth选项的限制),所以......小心。

用反斜杠重命名文件很简单:mv 'ab' 'newname'(只需引用它),但您需要的不止这些。

您需要:

  • 查找所有带有反斜杠的文件(例如abc)
  • 从文件名拆分路径(例如ab来自c)
  • 创建完整路径(例如a/b, 目录b在目录下a)
  • 旧文件移动到新名称下,在创建的路径下(例如,将abc重命名为目录中名为c的文件a/b)

像这样:

#!/bin/bash
find . -name '*\*' | while read f; do
base="${f%\*}"
file="${f##*\}"
path="${base//\//}"
mkdir -p "$path"
mv "$f" "$path/$file"
done

(编辑:正确处理带空格的文件名)

最新更新