是否可以?并且在撤销按字母顺序?
本质上,这是:如何按类型递归地将文件从目录及其子目录移动到另一个目录?
只是每个文件都没有移动到目标目录除非一个单独的进程已获取该目标目录中的唯一文件并将其移动到其他位置(因此目标文件夹为空并“准备好”将下一个文件移动到那里)。
答案1
你想要这样的东西吗?
#!/usr/bin/env bash
## This is the target path, the directory
## you want to copy to.
target="some/path with/spaces";
## Find all files and folders in the current directory, sort
## them reverse alphabetically and iterate through them
find . -maxdepth 1 -type f | sort -r | while IFS= read -r file; do
## Set the counter back to 0 for each file
counter=0;
## The counter will be 0 until the file is moved
while [ $counter -eq 0 ]; do
## If the directory has no files
if find "$target" -maxdepth 0 -empty | read;
then
## Move the current file to $target and increment
## the counter.
mv -v "$file" "$target" && counter=1;
else
## Uncomment the line below for debugging
# echo "Directory not empty: $(find "$target" -mindepth 1)"
## Wait for one second. This avoids spamming
## the system with multiple requests.
sleep 1;
fi;
done;
done
该脚本将运行,直到复制所有文件。如果目标为空,它只会将文件复制到其中$target
,因此它将永远挂起,除非另一个进程在文件进入时删除它们。
$target
如果您的文件名或文件名包含换行符 ( ) ,它将中断,\n
但对于空格和其他奇怪字符应该没问题。
答案2
简单的解决方案使用inotify-wait
从inotify-tools
:
#!/bin/bash
SOURCE=$1
DEST=$2
(
IFS=$'\n'
for FILE in $(find "$SOURCE" -type f | sort -r); do
mv "$FILE" "$DEST"
inotifywait -e moved_from "$DEST"
done
)
解释:
(IFS=$'\n' ...)
在子 shell 中运行脚本主体,其中内部字段分隔符
$IFS
设置为换行符,允许for
循环正确处理带有空格的文件名。该$'string'
语法使bash
中的转义序列得以解释string
,因此$'\n'
被正确解释为换行符。for FILE in $(find $SOURCE -type f | sort -r)
在及其子目录中构建文件的反向排序列表,
$SOURCE
并一次迭代一个文件,将 的值设置$FILE
为要移动的下一个文件。mv "$FILE" "$DEST"
将当前移动
$FILE
到$DEST
目录。inotifywait -e moved_from "$DEST"
建立一个
inotify
当文件移出监视目录时会触发监视。这将导致脚本在目录$DEST
清空时阻塞。假设$DEST
调用脚本时为空。