我在目录中有以下“结构”文件名:
ABC_abcabc_ver01.txt
ABC_abcabc_ver02.txt
ABC_abcabc_ver04.txt
DEF_defdef_ver01.txt
GHI_ghighi_ver01.txt
GHI_ghighi_ver08.txt
我想获得的是仅限最新版本的列表(文件名称中的最后一位数字),即
ABC_abcabc_ver04.txt
DEF_defdef_ver01.txt
GHI_ghighi_ver08.txt
请注意,数字不一定是连续的,并非所有文件都有多个版本。为简单起见,可以假设最大可能的版本是'09',但是有一个更通用的解决方案会很酷。我知道awk
(没有sed
),所以我很有可能理解基于awk
的想法。欢迎任何帮助。
答案 0 :(得分:3)
你可以ls -1 or find...
并管道:
awk -F '_ver' '{a[$1]=$2>a[$1]?$2:a[$1]}END{for(x in a)print x FS a[x]}'
使用您的数据作为标准输入进行测试:
kent$ awk -F '_ver' '{a[$1]=$2>a[$1]?$2:a[$1]}END{for(x in a)print x FS a[x]}' <<<"ABC_abcabc_ver01.txt
ABC_abcabc_ver02.txt
ABC_abcabc_ver04.txt
DEF_defdef_ver01.txt
GHI_ghighi_ver01.txt
GHI_ghighi_ver08.txt"
输出:
GHI_ghighi_ver08.txt
ABC_abcabc_ver04.txt
DEF_defdef_ver01.txt
修改强>
添加“评论”,OP询问:
awk -F '_ver' #use "_ver" as field separator
'{a[$1]=$2>a[$1]?$2:a[$1]} #build an arry(hashtable),key:1st field, value:2nd filed (I guess you understood a=b>a?b:a)
END{for(x in a)print x FS a[x]}'#at the end, print all elements from the array
答案 1 :(得分:2)
有一种方法可以用纯粹的bash来做到这一点:
#!/bin/bash
shopt -s extglob
declare -A filesDict
export LC_COLLATE=C # so that * expansion order is always the same
for curFile in *; do
extension=${curFile#*.}
filename=${curFile%%+([[:digit:]]).*} # get rid of the version number and extension
if [[ $curFile == "$filename"+([[:digit:]])".$extension" ]]; then # if doing it backwards results in the same filename. We do that to ignore other random files that might appear in a directory
filesDict["$filename.$extension"]=$curFile # add or overwrite value in the dictionary. Overwriting is always safe because files with the biggest version number will always come last (assuming that they're zero-padded)
fi
done
for curKey in "${!filesDict[@]}"
do
echo "File: $curKey Last version: ${filesDict[$curKey]}"
done
此脚本依赖于使用字母顺序展开*
的bash行为。我不确定所有语言环境是否都适合数字,所以我强制LC_COLLATE=C
只是为了确定。
现在,如果你忽略了这个脚本太棘手的事实,你会发现它实际上是一个非常好的解决方案,因为它可以处理你可以拥有的任何文件名(甚至那些在名称中有换行符的文件名)。 / p>
当您拥有相同的文件名但具有不同的扩展名(例如test01.txt
和test01.tar.gz
时,它也将处理这种情况,这些将被视为不同的文件)
它将忽略没有扩展名或没有版本号的文件。如果要包含没有版本号的文件,只需将+([[:digit:]])
更改为*([[:digit:]])
(请注意,脚本中有两次出现)。您也可以删除点以包含没有扩展名的文件名,但这是一个完全不同的故事。
答案 2 :(得分:0)
sort -t _ -k1,1 -k2,2 -k 3.4nr file|awk -F _ '!a[$1 FS $2]++'
ABC_abcabc_ver04.txt
DEF_defdef_ver01.txt
GHI_ghighi_ver08.txt
<强>解释强>
sort命令将按预期对文件进行排序:
ABC_abcabc_ver04.txt
ABC_abcabc_ver02.txt
ABC_abcabc_ver01.txt
DEF_defdef_ver01.txt
GHI_ghighi_ver08.txt
GHI_ghighi_ver01.txt
awk命令始终采用最新的一个(第一个)。