根据某种模式选择和移动独特的文件

vik*_*ana 2 shell-script rename mv

我在 Linux 机器上有一个文件列表,这些文件在某个日期上有所不同,所以我必须搜索唯一的文件并需要将它们放在其他目录中。“唯一”在这里指的是文件,直到第二的名字_,所以100001_ABC100001_XYZ在下面的例子。

100001_ABC_25Sep2020_1200-25Sep2020_1300.csv  
100001_XYZ_30Sep2020_1300-30Sep2020_1400.csv  
100001_XYZ_30Sep2020_1400-30Sep2020_1500.csv
Run Code Online (Sandbox Code Playgroud)

我希望将唯一命名的放在此目录下:

/home/vikrant_singh_rana/uniquefiles/
Run Code Online (Sandbox Code Playgroud)

该脚本应仅复制以下文件:

100001_ABC_25Sep2020_1200-25Sep2020_1300.csv  
100001_XYZ_30Sep2020_1300-30Sep2020_1400.csv  
Run Code Online (Sandbox Code Playgroud)

这是我的 shell 脚本

#!/bin/bash
set +o posix
#reading file names into file_array
readarray -t file_array < <(
    cd "/home/vikrant_singh_rana/unzipfiles"
    printf "%s\n" * | cut -d"_" -f2 | cut -d"-" -f1 | sort -u )

#print items of array
printf '%s\n' "${file_array[@]}"


for i in "${file_array[@]}"; do
        #echo $i
        find /home/vikrant_singh_rana/unzipfiles/ -type f -name "*$i*.csv" -exec awk '!seen[$0]++' {} +
done
Run Code Online (Sandbox Code Playgroud)

该脚本可以正确找到唯一名称,但我找不到如何将它们移动到另一个目录。

Sté*_*las 6

zsh.

typeset -A files
for f (*_*_*.csv(.On)) files[${(M)f#*_*_}]=$f
mv -- $files target-directory/
Run Code Online (Sandbox Code Playgroud)

.水珠预选赛限制了普通文件,而On各种以相反的顺序,这样在最后的关联数组包含按字母顺序对于给定的密钥(这里的部分到第二的第一个文件_)。

代替词法顺序,您可能希望o通过modification 时间进行rder(考虑到它100001_XYZ_01Oct2020_0000-01Oct2020_0100会出现 100001_XYZ_30Sep2020_2200-30Sep2020_2300例如词法顺序之前),通过替换Onom(将文件从最新到最旧排序),以便您最终将最旧的文件移动为与按词汇顺序排在第一位的相反。

或者您可以根据文件名中的第一个时间戳定义排序顺序:

zmodload zsh/datetime
bydate() strftime -rs REPLY %d%b%Y_%H%M ${${REPLY%-*}#*_*_}
Run Code Online (Sandbox Code Playgroud)

并使用nO+bydate代替On/ om

使用bashGNU 工具,您可以使用以下方法做一些接近的事情(不限于常规文件,也没有按修改时间排序):

shopt -s failglob
printf '%s\0' *_*_*.csv | sort -zsmut_ -k1,2 | xargs -r0 mv -t target-dir --
Run Code Online (Sandbox Code Playgroud)

(所有-z, -s, -r, -0,-t都是 GNU 扩展)。

可以通过从文件名中提取的时间戳进行排序:

printf '%s\0' *_*_*.csv |
                   #  key   year       month      day        HHMM
  LC_ALL=C sort -zt_ -k1,2 -k3.6,3.9n -k3.3,3.5M -k3.1,3.2n -k3.11,3.14n |
  LC_ALL=C sort -zsmut_ -k1,2 |
  xargs -r0 mv -t target-dir 
Run Code Online (Sandbox Code Playgroud)

如果,作为,您想要 的第一次和第二次出现之间的部分_,请替换${(M)f#*_*_}${${f#*_}%%_*}(或${${(s[_])f}[2]})或替换-k1,2-k2,2