我有一个目录my_dir
,其文件名为:
a_v5.json
a_v5.mapping.json
a_v5.settings.json
f_v39.json
f_v39.mapping.json
f_v39.settings.json
f_v40.json
f_v40.mapping.json
f_v40.settings.json
c_v1.json
c_v1.mapping.json
c_v1.settings.json
我正在寻找一种在bash中获取数组[a_v5, f_v40, c_v1]
的方法。在这里,我需要具有最新版本号的文件名数组。
对此进行了尝试:ls *.json | find . -type f -exec basename "{}" \; | cut -d. -f1
,但它返回的结果不是.json扩展名的文件。
答案 0 :(得分:2)
如果文件名不包含空格和*
或?
之类的特殊符号,则可以使用以下命令:
array=($(
find . -type f -iname \*.json |
sed -E 's|(.*/)*(.*_v)([0-9]+)\..*|\2 \3|' |
sort -Vr | sort -uk1,1 | tr -d ' '
))
这很丑陋而且不安全。以下解决方案更长,但可以处理所有文件名,即使其中包含换行符也是如此。
maxversions() {
find -type f -iname \*.json -print0 |
gawk 'BEGIN { RS = "\0"; ORS = "\0" }
match($0, /(.*\/)*(.*_v)([0-9]+)\..*/, group) {
prefix = group[2];
version = group[3];
if (version > maxversion[prefix])
maxversion[prefix] = version
}
END {
for (prefix in maxversion)
print prefix maxversion[prefix]
}'
}
mapfile -d '' array < <(maxversions)
在两种情况下,您都可以使用array
检查declare -p array
的内容。
答案 1 :(得分:1)
数组和bash字符串解析。
tata
或者,如果您愿意,
declare -A tmp=()
for f in $SOURCE_DIR/*.json
do f=${f##*/} # strip path
tmp[${f%%.*}]=1 # strip extraneous data after . in filename
done
declare -a c=( $( printf "%s\n" "${!tmp[@]}" | cut -c 1 | sort -u ) ) # get just the first chars
declare -a lst=( $( for f in "${c[@]}"
do printf "%s\n" "${!tmp[@]}" |
grep "^${f}_" |
sort -n |
tail -1; done ) )
echo "[ ${lst[@]} ]"
[ a_v5 c_v1 f_v40 ]
答案 2 :(得分:0)
这是完成此操作的一种可能方法:
arr=( $( { for name in $( ls {f,n,m}*.txt ); do echo ${name:0:1} ; done; } | sort | uniq ) )
$ echo ${arr[0]}
f
$ echo ${arr[1]}
m
$ echo ${arr[2]}
n
致谢!
答案 3 :(得分:0)
这不是一个很好的解决方案...我对awk的了解有限。 您应该找到此功能。
我已对此进行了更新,以删除@socowi建议的过时的uniq。 我还包括了@socowi建议的printf版本。
ls *.json | cut -d. -f1 | sort -rn | awk -v last="xx" '$1 !~ last{ print $1; last=substr($1,1,3) }'
OR
printf %s\\n *.json | cut -d. -f1 | sort -rn | awk -v last="xx" '$1 !~ last{ print $1; last=substr($1,1,3) }'
下面的旧理解
查找具有名称匹配模式的文件。
现在选择第二个字段,因为您的结果可能类似于./
find . -type f -iname "*.json" | cut -d. -f2
要获取唯一的标题。...
find . -type f -iname "*.json" | cut -d. -f2 | sort | uniq