我一直在尝试编写一个脚本来重命名所有包含空格的文件并用破折号替换空格。
示例:"嘿鲍勃.txt">到"嘿鲍勃.txt">
当我使用 for 循环时,它只是在空格处拆分文件名,因此"Hey Bob.txt"给出了单独的参数,如"Hey"和"Bob.txt"。
我尝试了以下脚本,但它一直挂在我身上。
#!/bin/bash
find / -name '* *' -exec mv {} $(echo {} | sed 's/ /-g');
基于OP的想法:
find ${PATH_TO_FILES} -name '* *' -exec bash -c 'eval $(echo mv -v "{}" $(echo {} | sed "s/ /-/g"))' ;
- 注意:需要指定
PATH_TO_FILES
变量
编辑:BroSlow指出需要考虑目录结构:
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
另一种方式:
find . -name "* *" -type f |while read file
do
new=${file// /}
mv "${file}" $new
done
不是一行,但避免了sed
,如果你无论如何都要将其用于脚本,应该也能正常工作。(如果要测试,请将mv
替换为echo
)
在 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
较老的狂欢
#!/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// /-}
用-
替换文件名中的每个空格(我们事先检查连字符版本是否存在,如果它确实回显它未能 stderr,请注意&&
在 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