vik*_*ana 2 shell-script rename mv
我在 Linux 机器上有一个文件列表,这些文件在某个日期上有所不同,所以我必须搜索唯一的文件并需要将它们放在其他目录中。“唯一”在这里指的是文件,直到第二的名字_
,所以100001_ABC
并100001_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)
该脚本可以正确找到唯一名称,但我找不到如何将它们移动到另一个目录。
与zsh
.
typeset -A files
for f (*_*_*.csv(.On)) files[${(M)f#*_*_}]=$f
mv -- $files target-directory/
Run Code Online (Sandbox Code Playgroud)
该.
水珠预选赛限制了普通文件,而On
各种以相反的顺序,这样在最后的关联数组包含按字母顺序对于给定的密钥(这里的部分到第二的第一个文件_
)。
代替词法顺序,您可能希望o
通过m
odification 时间进行rder(考虑到它100001_XYZ_01Oct2020_0000-01Oct2020_0100
会出现在 100001_XYZ_30Sep2020_2200-30Sep2020_2300
例如词法顺序之前),通过替换On
为om
(将文件从最新到最旧排序),以便您最终将最旧的文件移动为与按词汇顺序排在第一位的相反。
或者您可以根据文件名中的第一个时间戳定义排序顺序:
zmodload zsh/datetime
bydate() strftime -rs REPLY %d%b%Y_%H%M ${${REPLY%-*}#*_*_}
Run Code Online (Sandbox Code Playgroud)
并使用nO+bydate
代替On
/ om
。
使用bash
GNU 工具,您可以使用以下方法做一些接近的事情(不限于常规文件,也没有按修改时间排序):
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
。