排序和复制文件

排序和复制文件

我是这里的新手,请耐心等待。

我有一个包含数千个文件的目录。文件名始终以 1 或 2 个字母开头,下划线“_”之前有 4 个字符。每个模式的文件数量可以不同,文件名下划线后的部分会发生变化。

样本:

Parentdir:
->AA01_*.pdf 
->AA01_*.html
->AA01_*.txt
...
->ZZ99_*.pdf
->ZZ99_*.html
->ZZ99_*.txt
...
->A001_*.pdf
->A001_*.html
->A001_*.txt
...
->Z999_*.pdf
->Z999_*.html
->Z999_*.txt

我想运行一个命令,仅使用文件名中的字母创建新目录,并用以这些字母开头的文件填充它们。如果目标目录中有一个同名的文件(源目录中的更新文件),我想保留最新的文件。所以:

New dir/files:
->AA
  AA01_*.pdf
  AA01_*.html
  AA01_*.txt
...
->ZZ
  ZZ99_*.pdf
  ZZ99_*.html
  ZZ99_*.txt
...
->A
  A001_*.pdf
  A001_*.html
  A001_*.txt
...
->Z
  Z999_*.pdf
  Z999_*.html
  Z999_*.txt

这能实现吗?

谢谢!

答案1

遍历文件集。选择字母前缀。创建目录(如果需要)并将文件移入其中。

#!/bin/sh
for item in *
do
    if [ -f "$item" ]
    then
        prefix="$(echo "$item" | sed 's/[^A-Z].*//')"
        echo mkdir -p "$prefix"
        echo mv "$item" "$prefix/"
    fi
done

删除echo前缀mkdirmv当您满意时,它就会执行您想要的操作。

答案2

使用珀尔 rename实用程序(在某些 Linux 发行版上prename又称为file-rename, perl-rename):

rename  -n  'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' *

注意:这有效仅有的使用基于 perl 的重命名实用程序。您可以通过运行rename -V(或prename -Vfile-rename -V或)来检查是否已安装它perl-rename -V。如果提到了 perl 或File::Rename,那么它就是 的 perl 版本rename。否则,rename它可能是util-linux完全不同的不相容功能和命令行选项。这会不是使用 util-linux 的 rename (或任何其他版本的 rename - 它)需要Perl 重命名)

这使用每个匹配文件名的前一个或两个“单词”字符(非贪婪匹配)作为目录,然后创建目录,并将文件重命名到目录中。 “单词”字符 ( \w) 的定义man perlre如下:

“匹配“单词”字符(字母数字加“_”,加上其他连接标点符号加 Unicode 标记)”

如果这不是您想要的,您可以使用例如[[:alpha:]]{1,2}?代替\w{1,2}?任何字母字符或[[:upper:]]{1,2}仅大写字符来优化模式。

\d数字。如果你想允许任何下划线之前的单词字符,使用\w.或者,[[:alnum:]]如果您只想允许字母和数字字符,请使用。

与整个模式不匹配的文件名(1 个或 2 个“单词”字符,后跟至少两个数字,后跟下划线)不受影响。

注:-n选项使其成为空运行操作。它只会显示它的内容做,但没有真正做。一旦您确定它满足您的要求,请删除-n(或将其替换-v为详细输出)。

例如给出以下设置脚本:

#!/bin/bash

for i in A AA Z9 ZZ  ; do
  for j in {01..10} ; do
    touch "$i${j}_.txt"
  done
done

# anomaly
touch A1001_.txt
$ ./setup.sh
$ ls
A01_.txt  A02_.txt  A03_.txt A04_.txt  A05_.txt  A06_.txt  A07_.txt  A08_.txt
A09_.txt A1001_.txt A10_.txt AA01_.txt AA02_.txt AA03_.txt AA04_.txt AA05_.txt
AA06_.txt AA07_.txt AA08_.txt AA09_.txt AA10_.txt setup.sh* Z901_.txt
Z902_.txt Z903_.txt Z904_.txt Z905_.txt Z906_.txt Z907_.txt Z908_.txt
Z909_.txt Z910_.txt ZZ01_.txt ZZ02_.txt ZZ03_.txt ZZ04_.txt ZZ05_.txt
ZZ06_.txt ZZ07_.txt ZZ08_.txt ZZ09_.txt ZZ10_.txt

运行 perl 重命名脚本后:

$ rename 'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' *
$ ls */*
A/A01_.txt   A/A02_.txt   A/A03_.txt   A/A04_.txt   A/A05_.txt A/A06_.txt
A/A07_.txt   A/A08_.txt   A/A09_.txt   A/A1001_.txt A/A10_.txt AA/AA01_.txt
AA/AA02_.txt AA/AA03_.txt AA/AA04_.txt AA/AA05_.txt AA/AA06_.txt
AA/AA07_.txt AA/AA08_.txt AA/AA09_.txt AA/AA10_.txt Z/Z901_.txt
Z/Z902_.txt  Z/Z903_.txt  Z/Z904_.txt  Z/Z905_.txt  Z/Z906_.txt  Z/Z907_.txt
Z/Z908_.txt  Z/Z909_.txt  Z/Z910_.txt ZZ/ZZ01_.txt ZZ/ZZ02_.txt ZZ/ZZ03_.txt
ZZ/ZZ04_.txt ZZ/ZZ05_.txt ZZ/ZZ06_.txt ZZ/ZZ07_.txt ZZ/ZZ08_.txt
ZZ/ZZ09_.txt ZZ/ZZ10_.txt

答案3

欢迎来到论坛,Zica!

我想建议organize- 如果您有耐心,您可以创建一个脚本,yaml可以在给定位置搜索文件、重命名、移动、排序,凡是您能想到的!我自己用的。我不知道你对 Linux 的熟练程度,但是 Git 有一个 readthedocs,它以一种非常容易理解的方式解释了你需要的一切。

相关内容