为递归目录中的每个文件创建文件夹,将文件放在文件夹中



在递归目录中为每个文件创建文件夹,将文件放入文件夹

在MacOS上,到目前为止我有…

for file in $(ls -R); do 
if [[ -f "$file" ]]; then mkdir "${file%.*}"; mv "$file" "${file%.*}"; fi; 
done

此操作在嵌套文件夹的顶层正确运行,但在较低的层级不做任何操作。

为了隔离错误,我尝试了这个,在rtf文件上操作。

for i in $(ls -R);do
if [ $i = '*.rtf' ];then
echo "I do something with the file $i"
fi
done

这个挂起,所以我简化为。.

for i in $(ls -R); do echo "file is $i" done

这个也挂了,所以我试了。

for i in $(ls -R); do echo hello

That hang also.

ls -R提供所有文件的递归列表。

建议感谢!!

首先不要在脚本中使用ls。它的目的是交互式地显示输出。虽然新的GNUls版本有一些shell解析的功能/选项,但不确定在Mac上是否可以。

现在使用findsh外壳。

find . -type f -name '*.rtf' -execdir sh -c '
for f; do mkdir -p -- "${f%.*}" && mv -v -- "$f" "${f%.*}"; done' _ {} +

无论出于何种原因-execdir不可用,都可以使用-exec

find . -type f -name '*.rtf' -exec sh -c '
for f; do mkdir -p -- "${f%.*}" && mv -v -- "$f" "${f%.*}" ; done' _ {} +
  • 看到Understanding-the-exec-option-of-find

给定如下文件结构:

$ tree .
.
├── 123
│   └── test_2.rtf
├── bar
│   ├── 456
│   │   └── test_1.rtf
│   └── 789
└── foo

有两种常见的方法来查找该树中的所有.rtf文件。第一种(也是最常见的)是使用find:

while IFS= read -r path; do 
echo "$path"
done < <(find . -type f -name "*.rtf")

打印:

./bar/456/test_1.rtf
./123/test_2.rtf

第二种常用方法是使用递归glob。这不是POSIX的方式,只在最近的shell中发现,如Bash, zsh等:

shopt -s globstar            # In Bash, this enables recursive globs
# In zsh, this is not required
for path in **/*.rtf; do 
echo "$path"
done 
# same output

现在您有了查找文件的循环,您可以修改找到的文件。

你会遇到的第一个问题是你不能在一个目录下有两个同名的文件;目录只是一种文件。所以你需要这样做:

  1. 查找所有文件及其路径;
  2. 创建tmp名称并使用该临时名称创建子目录;
  3. 将找到的文件移动到临时目录;
  4. 将临时目录重命名为找到的文件名。

这是一个Bash(或MacOS默认的zsh)脚本:

shopt -s globstar              # remove for zsh
for p in **/*.rtf; do 
[ -f "$p" ] || continue    # if not a file, loop onward
tmp=$(uuidgen)             # easy temp name -- not POSIX however
fn="${p##*/}"              # strip the file name from the path
path_to="${p%/*}"          # get the path without the file name
mkdir "${path_to}${tmp}"   # use temp name for the directory 
mv "$p" "${path_to}$tmp"   # move the file to that directory
mv "${path_to}$tmp" "$p"   # rename the directory to the path
done 

和结果:

.
├── 123
│   └── test_2.rtf
│       └── test_2.rtf
├── bar
│   ├── 456
│   │   └── test_1.rtf
│   │       └── test_1.rtf
│   └── 789
└── foo

最新更新