Bash - 寻找带有空格的文件并使用 sed 重命名
在Bash中,如果文件名包含空格,可能会导致一些问题。例如,当需要查找包含空格的文件并对其进行重命名时,通常会遇到一些困难。下面的代码演示了如何解决这个问题。
对于Bash 4及以上的版本,可以使用以下代码:
#!/bin/bash shopt -s globstar for file in **/*; do filename="${file##*/}" if [[ -f $file && $filename == *" "* ]]; then onespace=$(echo $filename) dir="${file%/*}" [[ ! -f "$dir/${onespace// /-}" ]] && mv "$file" "$dir/${onespace// /-}" || echo "$dir/${onespace// /-} already exists, so not moving $file" 1>&2 fi done
对于较旧的Bash版本,可以使用以下代码:
#!/bin/bash find . -type f -print0 | while read -r -d '' file; do filename="${file##*/}" if [[ -f $file && $filename == *" "* ]]; then onespace=$(echo $filename) dir="${file%/*}" [[ ! -f "$dir/${onespace// /-}" ]] && mv "$file" "$dir/${onespace// /-}" || echo "$dir/${onespace// /-} already exists, so not moving $file" 1>&2 fi done
这段代码的作用是查找当前目录中包含空格的文件,并将空格替换为短横线进行重命名。下面是算法的解释:
- `**/*` 递归列出当前目录中的所有文件(`**`表示递归,`/*`用于排除目录本身)
- `${file##*/}` 搜索文件中最长的`*/`模式,并将其从字符串中删除。例如,`/foo/bar/test.txt`输出为`test.txt`
- `$(echo $filename)` 在不引用的情况下,echo会将空格截断为一个空格,使得更容易用一个`-`替换任意数量的空格
- `${file%/*}` 删除最后一个`/`及其之后的所有内容。例如,`/foo/bar/test.txt`输出为`/foo/bar`
- `mv "$file" ${onespace// /-}` 将文件名中的每个空格替换为`-`(在替换前,我们会检查是否已经存在带有短横线的版本,如果存在则将错误消息输出到标准错误输出,注意,在Bash中,`&&`在`||`之前执行)
- `find . -type f -print0 | while read -r -d '' file` 使用这个命令可以避免使用空格分隔字符串,通过设置分隔符并不处理`\`
运行脚本的示例输出如下:
$ tree . ├── bar │ ├── some dir │ │ ├── some-name-without-space1.pdf │ │ ├── some name with space1.pdf │ ├── some-name-without-space1.pdf │ ├── some name with space1.pdf │ └── some-name-with-space1.pdf └── space.sh $ ./space.sh bar/some-name-with-space1.pdf already exists, so not moving bar/some name with space1.pdf $ tree . ├── bar │ ├── some dir │ │ ├── some-name-without-space1.pdf │ │ ├── some-name-with-space1.pdf │ ├── some-name-without-space1.pdf │ ├── some name with space1.pdf │ └── some-name-with-space1.pdf └── space.sh
通过上述方法,我们可以轻松地在Bash中查找包含空格的文件并对其进行重命名,避免了因为文件名中的空格而导致的问题。
Bash - 查找带有空格的文件并使用sed进行重命名
在Bash命令行中,有时我们需要查找文件名中包含空格的文件,并对它们进行重命名。然而,由于文件名中包含特殊字符或换行符,上述的解决方法并不够稳健和完善。
原因:
上述的解决方法使用了find命令来查找文件名中包含空格的文件,并使用sed命令将空格替换为空。然而,如果文件名中存在其他特殊字符,如引号、斜杠等,这种方法就无法正常工作。而且,如果文件名中包含换行符,这种方法也无法处理。
解决方法:
为了解决上述问题,我们可以使用更加稳健的方法来查找和重命名带有空格的文件。一个可行的解决方案是使用find命令的-exec选项结合sed命令来进行重命名。具体步骤如下:
1. 打开终端,进入需要进行操作的目录。
2. 使用以下命令来查找文件名中包含空格的文件:
find . -name "* *" -type f -exec sh -c 'mv "$0" "${0// /}"' {} \;
- find命令用于查找文件;
- -name选项指定查找的文件名模式,"* *"表示查找文件名中包含空格的文件;
- -type选项指定查找的文件类型为普通文件;
- -exec选项用于执行后续的命令,{}表示匹配到的文件名。
3. 执行以上命令后,文件名中的空格将会被替换为空,并完成文件的重命名。
这种方法更加稳健,能够处理文件名中包含其他特殊字符的情况,并且也能处理文件名中包含换行符的情况。但需要注意的是,这种方法只能处理当前目录及其子目录下的文件,如果需要处理其他目录下的文件,需要修改find命令中的路径参数。
通过使用find命令的-exec选项结合sed命令,我们可以更加稳健地查找和重命名文件名中包含空格的文件。这种方法可以处理文件名中包含其他特殊字符和换行符的情况,提高了操作的稳定性和可靠性。希望这篇文章对你在Bash命令行中查找和重命名文件名中包含空格的文件有所帮助。
Bash中查找带有空格的文件并使用sed重命名的问题是由以下内容引起的。解决方法如下:
首先,需要注意指定PATH_TO_FILES
变量。然后,考虑到目录结构,需要对其进行修改。可以使用以下命令:
find ${PATH_TO_FILES} -name '* *' -exec bash -c 'DIR=$(dirname "{}" | sed "s/ /-/g" ); BASE=$(basename "{}"); echo mv -v \"$DIR/$BASE\" \"$DIR/$(echo $BASE | sed "s/ /-/g")\"' \; > rename-script.sh ; sh rename-script.sh
在这个命令中,我们添加了-type f
以避免错误。这是一个很好的一行命令。但是,我们还需要考虑到如果OP想要重命名'Hey Bob'目录,甚至是'Hey Bob'符号链接的情况。这可能是OP想要的,但这将完全改变目录树,而且在一行命令中仍然需要在mv文件之前创建不存在的目录。因此,即使mv在上面的示例中正确处理,它也会失败,因为它将尝试将其mv到“/home/foo/some-space-sir/some-file”。