我们目前正在 Linux 上测试一个以前在 Windows 上运行的新应用程序。程序中似乎存在一些硬编码路径,并且创建了一堆带有反斜杠的长文件名的测试文件。例如:
directory\subdirectory\subdirectory\subdirectory\filename.ext
我需要获取这些文件,创建它们应该所在的目录并将它们移动到那里。因此,例如,上面的文件实际上应该是:
directory/subdirectory/subdirectory/subdirectory/filename.ext
我怎样才能做到这一点?
答案1
如果您需要重命名全部名称包含 的文件\
,您可以执行以下操作:
for file in *\\*; do
dir="$(dirname -- "${file//\\/\/}")"
filename="${file##*\\}"
mkdir -p -- "$dir"
mv -- "$file" "$dir"/"$filename"
done
解释
for file in *\\*
:glob*\\*
匹配当前目录中名称中包含\
.因为\
也是转义字符,所以我们需要对其进行转义,以便将其视为文字。这就是为什么我们不能只使用*\*
.然后,这将迭代名称包含 的所有文件和目录
\
,并将它们每个保存为$file
.dir="$(dirname "${file//\\/\/}")"
:${file//\\/\/}
将打印当前文件名,并全部\
替换为/
.需要转义\\
和),因为和都是特殊字符。打印文件所在的目录。例如,将返回.因此,将是我们想要将此文件移动到的目标目录。\/
\
/
dirname
dirname /path/to/file
/path/to
$dir
filename=${file##*\\}
:文件名,\
删除最后一个之前的所有内容。这是实际的文件名,将另存为$filename
.mkdir -p "$dir"
:创建目标目录及其所有父目录。 make-p
创建mkdir
父目录(没有父目录mkdir foo/bar
将无法工作,除非foo/
已经存在),并且还使其忽略有关已存在目录的错误。mv "$file" "$dir"/"$filename"
:最后一步,将文件移动到正确的位置。
答案2
prename 'mkdir $` while s[\\][/]' *\\*
prename
Perl 实用程序在哪里,有时rename
也称为。该命令的基本操作模型是通过其命令行向其提供需要更改的文件名,在我们的例子中,*\\*
将提供名称中至少包含反斜杠的所有文件名。
然后,单引号中的代码将一一应用于文件名,得到的$_
就是新文件名。
我们设置一个while
循环,逐步将反斜杠一次更改为斜杠,并创建 $` var 指向的目录,该目录是字符串的预匹配部分。
当我们退出 while 循环时,$_
包含目录/子目录/子目录/子目录/文件名.ext,这就是原始目录被重命名为的目录/子目录现在都存在。