根據某種模式選擇和移動獨特的文件
我有一個 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
我希望將唯一命名的放在此目錄下:
/home/vikrant_singh_rana/uniquefiles/
該腳本應僅複製以下文件:
100001_ABC_25Sep2020_1200-25Sep2020_1300.csv 100001_XYZ_30Sep2020_1300-30Sep2020_1400.csv
這是我的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
該腳本可以正確找到唯一名稱,但我找不到如何將它們移動到另一個目錄。
與
zsh
.typeset -A files for f (*_*_*.csv(.On)) files[${(M)f#*_*_}]=$f mv -- $files target-directory/
.
glob 限定符限制為正常文件,同時以On
相反的順序排序,以便最後關聯數組包含給定鍵的按字母順序排列的第一個文件(此處為第二個部分_
)。而不是詞法順序,您可能希望
o
通過m
修改時間來代替(考慮例如在詞法順序中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%-*}#*_*_}
並使用
nO+bydate
代替On
/om
。使用
bash
GNU 工具,您可以做一些接近的事情(不限於正常文件,但不按修改時間排序):shopt -s failglob printf '%s\0' *_*_*.csv | sort -zsmut_ -k1,2 | xargs -r0 mv -t target-dir --
(所有
-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
如果作為鍵,您想要第一次和第二次出現之間的部分
_
,請替換${(M)f#*_*_}
為${${f#*_}%%_*}
(或${${(s[_])f}[2]}
)或-k1,2
替換為-k2,2
。
這是任何文件名的解決方案:
target_dir="path/to/dir" find -maxdepth 1 -type f -name '*.csv' -print0 | sort -z | awk ' BEGIN {RS=ORS="\0"; FS=OFS="_"} !seen[$2]++' | xargs -r0 echo mv -t "$target_dir" --
我們通過管道使用空分隔符來保護文件名,
sort
按字母順序獲取它們並GNU awk
排除重複項。測試它,如果它列印出合理的移動命令,請刪除echo
以執行它。(以上所有用於空分隔的都是 GNU 擴展
-z
等)這更簡單,因為如果您的文件名非常好,您可以簡單地執行以下操作:
ls -1 *.csv | awk -F_ '!seen[$2]++' | xargs -d'\n' echo mv -t target/dir --
請注意,glob 按字母順序獲取文件。