我一直在尝试编写一个脚本来重命名包含空格的所有文件,并用短划线替换空格。
示例:“Hey Bob.txt”改为“Hey-Bob.txt”
当我使用for循环时,它只是在空格处分割文件名,因此“Hey Bob.txt”给出了单独的参数,如“Hey”和“Bob.txt”。
我尝试了以下脚本,但它一直挂在我身上。
#!/bin/bash
find / -name '* *' -exec mv {} $(echo {} | sed 's/ /-g')\;
答案 0 :(得分:1)
建立OP的想法:
find ${PATH_TO_FILES} -name '* *' -exec bash -c 'eval $(echo mv -v \"{}\" $(echo {} | sed "s/ /-/g"))' \;
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
答案 1 :(得分:0)
不是一行,但是避免使用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
较旧的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)
如果没有引用,则会将空格截断为一个,这样就可以更轻松地替换任意个空格的-
${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
答案 2 :(得分:0)
另一种方式:
find . -name "* *" -type f |while read file
do
new=${file// /}
mv "${file}" $new
done