我可以使用什么命令将文件从一个目录移动到另一个目录,从较小的尺寸开始到较大的尺寸?

我可以使用什么命令将文件从一个目录移动到另一个目录,从较小的尺寸开始到较大的尺寸?

我正在寻找一个 Linux 命令,可以按文件大小的升序将文件从一个目录移动到另一个目录,例如,第一个文件大小为 1 Mb,然后是 1.2 Mb,然后是 1.3 Mb 等等。

答案1

如果您要将单个目录中的文件移动到另一个单个目录中,则可以使用ls可以按大小对文件进行排序的命令。以下脚本将按照文件大小增加的顺序将文件从源目录(作为第一个参数给出)移动到目标目录(作为第二个参数给出):

#!/usr/bin/env bash
src="$1"
dst="$2"
if [[ ! -d "$src" ]] ; then
  echo "Source directory $src does not exist!"
  exit 1
fi
if [[ ! -d "$dst" ]] ; then
  echo "Destination directory $dst does not exist!"
  exit 2
fi
cd "$src" || exit
ls -arS | while read -r f ; do
  if [[ -f "$f" ]] ; then
    echo mv "$f" "$dst"
  fi
done

echo一旦您确认脚本运行正常,您就可以删除该命令。

答案2

在里面壳牌zsh),利用其Glob 限定符,你可以这样做(从源目录中):

Withzsh的内置函数zmv

% autoload zmv
%
% zmv -Q -n -- '*(.oL)' '/path/to/target/$f'

注意:该选项-n用于试运行...当对输出满意时,用-v详细程度) 才能真正发生移动。

或使用外部/bin/mv(首先,请参阅下面的试运行通知):

printf '%s\0' *(.oL) | xargs -0 mv -nv -t /path/to/target/ --

或者一次移动一个文件:

printf '%s\0' *(.oL) | xargs -0 -I {} mv -nv -- {} /path/to/target/

注意:对于试运行,你可以使用如下方法:

printf '%s\0' *(.oL) | xargs -0 stat --printf='Name: %n Size: %s\n'

位于*(.oL):

  • .表示纯文件。
  • o表示按升序排序。
  • L表示文件的大小(长度)。

答案3

这是在源目录中运行的多行单行命令:

find -type f -printf '%s/%p\0' | # get paths with sizes together into safe zero-delimited lines
    sort -zn | # do numeric sort (ascending)
    cut -zd/ -f2- | #cut the sizes down
    xargs -0 cp -v --parents --target-directory="../B/" # do the copy

笔记:

  • 不要忘记cd path/to/source/dir
  • "../B/"用目标目录的相对路径或绝对路径替换。
  • 文件名可以包含任何字符,包括空格、换行符$%^<>""和其他棘手的内容。
  • 保留路径,在目标上创建必要的子文件夹。
  • 可以省略-v以保持cp沉默。
  • 元数据未保留,cp请使用--preserve=all
  • 此脚本复制文件,而不是移动文件。原因是:
  1. 没有mv --parents命令,我懒得模仿它。
  2. 在一个文件系统中,您可以简单地将整个源目录重命名为目标,这使得文件被“移动”瞬间。但是,无论如何,移动至其他文件系统都是通过复制+删除源序列完成的。

以下是我理解您的数据集/创建测试数据的方式:

# making test dirs
mkdir test/{,A,B}
cd test/A
mkdir sub{1..4} sub1/sub{1..2}
# making test file of random sizes
find -mindepth 1 -type d -exec sh -c 'cd "$1"; x=${RANDOM}0; dd if=/dev/urandom of=${RANDOM}.${x}.bin count=${x}' - {} \;
$ tree -s .. # review
..
├── [          0]  A
│   ├── [          0]  sub1
│   │   ├── [   89502720]  5334.174810.bin
│   │   ├── [          0]  sub1
│   │   │   └── [  126310400]  24545.246700.bin
│   │   └── [          0]  sub2
│   │       └── [  124303360]  17288.242780.bin
│   ├── [          0]  sub2
│   │   └── [  149780480]  22029.292540.bin
│   ├── [          0]  sub3
│   │   └── [    9246720]  19263.18060.bin
│   └── [          0]  sub4
│       └── [  110320640]  31098.215470.bin
└── [          0]  B

8 directories, 6 files

清单:

$ find -type f -printf '%s/%h/%f\0' | sort -zn | cut -zd/ -f2- | tr '\0' '\n' | xargs -l ls -lh
-rw-r--r-- 1 user group 8.9M Aug  7 14:31 ./sub3/19263.18060.bin
-rw-r--r-- 1 user group 86M Aug  7 14:30 ./sub1/5334.174810.bin
-rw-r--r-- 1 user group 106M Aug  7 14:31 ./sub4/31098.215470.bin
-rw-r--r-- 1 user group 119M Aug  7 14:30 ./sub1/sub2/17288.242780.bin
-rw-r--r-- 1 user group 121M Aug  7 14:30 ./sub1/sub1/24545.246700.bin
-rw-r--r-- 1 user group 143M Aug  7 14:31 ./sub2/22029.292540.bin

怎么运行的:

$ find -type f -printf '%s/%p\0' | # get paths with sizes together into safe zero-delimited lines
    sort -zn | # do numeric sort (ascending)
    cut -zd/ -f2- | #cut the sizes down
    xargs -0 cp -v --parents --target-directory="../B/" # do the copy
./sub3 -> ../B/./sub3
'./sub3/19263.18060.bin' -> '../B/./sub3/19263.18060.bin'
./sub1 -> ../B/./sub1
'./sub1/5334.174810.bin' -> '../B/./sub1/5334.174810.bin'
./sub4 -> ../B/./sub4
'./sub4/31098.215470.bin' -> '../B/./sub4/31098.215470.bin'
./sub1/sub2 -> ../B/./sub1/sub2
'./sub1/sub2/17288.242780.bin' -> '../B/./sub1/sub2/17288.242780.bin'
./sub1/sub1 -> ../B/./sub1/sub1
'./sub1/sub1/24545.246700.bin' -> '../B/./sub1/sub1/24545.246700.bin'
./sub2 -> ../B/./sub2
'./sub2/22029.292540.bin' -> '../B/./sub2/22029.292540.bin'

答案4

您可以使用查找。

find . -size +1M将递归地查找当前目录中每个超过 1MB 的文件。

添加后-exec我们就可以移动文件了:

find . -type f -size +1M -exec mv "{}" large_files/ \;

可以使用 bash 脚本将其制成循环:

for size in $(seq 2 -0.1 1)
do
mkdir -p "${size}"_files
find . -type f -size +"${size}"M -exec mv {} large_files/ \;
done

这里seq将生成 2 到 1 之间的数字,以 0.1 为增量,例如 2、1.9 等。我们必须按相反的顺序执行,因为大于 1MB 的文件也会匹配 2MB 的文件,因此使用负增量。

mkdir将为每种大小创建一个目录,find 将查找文件并将其移动到目录中。-p如果目录已存在,则确保不会打印任何错误。

相关内容