>我得到了一个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
(编辑:正确处理带空格的文件名)