[英]Replace spaces in files within subdirectories
I have about 10,000 directories containing files.我有大约 10,000 个包含文件的目录。 I want to write a loop that iterates through each directory, picks out a.
我想写一个循环遍历每个目录,挑出一个。
txt
file, and replaces any spaces with a _
. txt
文件,并将所有空格替换为_
。 How can I do this?我怎样才能做到这一点?
for f in *FOLDERS*
do
cd "$f" && echo "Entering into $f" || { echo "Error: could not enter into $f"; continue; }
for y in $(ls *.txt | mv "$y" "${y// /_}")
do
echo ${y}
done
done
But it doesn't work for each directory.但它不适用于每个目录。 What am i doing wrong?
我究竟做错了什么?
This might be what you're trying to do:这可能是你想要做的:
#!/bin/bash
for d in */; do
cd "$d" || exit
for t in *\ *.txt; do
[[ -f $t ]] && mv -i "$t" "${t// /_}"
done
cd ..
done
Or, if you want to do it recursively (for all subdirectories in any depth):或者,如果您想递归地执行此操作(对于任何深度的所有子目录):
#!/bin/bash
shopt -s globstar
for d in **/; do
cd "$d" || exit
for t in *\ *.txt; do
[[ -f $t ]] && mv -i "$t" "${t// /_}"
done
cd - >/dev/null
done
_
._
。mv
.mv
。find *FOLDERS* -type f -name '* *.txt' -print0 |
# Duplicate the line. Replace spaces by _ in the second line.
sed -Ez 'h ; s@.*/@@ ; s@ @_@g ; G ; s@([^\x00]*)\x00(.*/)?([^/]*)@\2\3\x00\2\1@' |
# Execute mv for each two arguments.
xargs -0 -n2 echo mv -v
Select files with find
, then run bash
to perform the filename manipulation. find
个文件,然后运行bash
来执行文件名操作。
find . -type f -name '* *.txt' -exec bash -c 'for path; do
basename="${path##*/}"
dir="${path%/*}"
echo mv "$path" "$dir"/"${basename// /_}"
done' - {} +
This is fully recursive;这是完全递归的; if you don't want that you can limit the selection depth with
find
.如果您不想,可以使用
find
限制选择深度。 The other advantage to using find
is you can tell for sure what files you will be operating on before you run the dangerous part.使用
find
的另一个好处是,在运行危险部分之前,您可以确定要对哪些文件进行操作。
The above is harmless as-is, to make it actually perform its function remove the echo
before the mv
.上面是无害的,让它实际执行它的 function 删除
mv
之前的echo
。
This is why your script is not working.这就是您的脚本不起作用的原因。 Consider this folder structure:
考虑这个文件夹结构:
$ ls
d1 d2 d3
Now lets try to cd
into each folder:现在让我们尝试
cd
进入每个文件夹:
$ for d in *; { cd $d; pwd; }
/tmp/d1
bash: cd: d2: No such file or directory
/tmp/d1
bash: cd: d3: No such file or directory
/tmp/d1
You have to go back to 'home' folder first:您必须先 go 回到“主”文件夹:
$ for d in *; { cd $d; pwd; cd ..; }
/tmp/d1
/tmp/d2
/tmp/d3
Or use full path in $d
definition:或者在
$d
定义中使用完整路径:
$ for d in $PWD/*; { cd $d; pwd; }
/tmp/d1
/tmp/d2
/tmp/d3
For something fast, you will probably want Sorpigal's answer;对于快速的事情,您可能需要 Sorpigal 的回答; this will still work, but it's slower.
这仍然有效,但速度较慢。
#!/bin/sh -x
find . -type f -name '* *.txt' > stack
next () {
[[ -s stack ]] && main
end
}
main () {
line=$(sed -n "1p" stack)
echo "${line}" | tr '/' '\n' > f2
basename=$(sed -n "$p" f2)
sed -i "$d" f2
dirname=$(cat f2 | tr '\n' '/')
newname=$(echo "${basename}" | tr ' ' '_')
mv -v "${dirname}/${basename}" "${dirname}/${newname}"
sed -i "1d" stack
rm -v ./f2
next
}
end () {
rm -v ./stack
exit 0
}
next
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.