在显示原始文件名的同时按最后分隔的子字符串对目录中的文件进行排序

问题描述 投票:0回答:3

我有一个目录,其中包含以时间戳结尾的文件。我想按名称中的时间戳顺序遍历此目录中的文件。我在 Unix 的 shell 脚本中这样做。

filename1_20230517_065806.txt
filename2_20230517_055806.txt
filename_3_20230517_125806.txt
file_name_4_20230517_063806.txt

我需要按以下顺序处理

filename2_20230517_055806.txt
file_name_4_20230517_063806.txt
filename1_20230517_065806.txt
filename_3_20230517_125806.txt

命令应该只看文件名的时间部分。我希望做这样的事情,但由于提交的名称可以有任意数量的下划线,所以我遇到了困难。

for i in $(ls *.txt | sort -t'_' -k3)
do...

有没有一种方法可以查看最后一个分隔索引并按它排序?

shell sorting unix
3个回答
0
投票

我认为为此您需要 awk 的帮助,使用“技巧”通过在每一行前面加上所需的排序键来临时扩充数据。我也将日期 ($(NF-1)) 添加到下面的排序键中。

for i in $(ls *.txt | awk -F_ ‘{print $(NF-1) $NF “\t” $0}’ | sort | cut -f 2-) do...


0
投票

您可以使用“rev”来反转元素,而不是对前两个元素进行排序:

#!/bin/bash

filenames="filename1_20230517_065806.txt filename2_20230517_055806.txt filename_3_20230517_125806.txt file_name_4_20230517_063806.txt"

# Convert the filenames string into an array
IFS=' ' read -r -a files_array <<< "$filenames"

# Sort the array based on the timestamp with reversed elements
sorted_array=($(for file in "${files_array[@]}"; do
  timestamp=$(echo "$file" | rev | cut -d_ -f1,2 | rev)
  echo "$timestamp $file"
done | sort | cut -d' ' -f2))

for file in "${sorted_array[@]}"; do
  echo "$file"
done

输出看起来像预期的那样:

filename2_20230517_055806.txt
file_name_4_20230517_063806.txt
filename1_20230517_065806.txt
filename_3_20230517_125806.txt

0
投票
$ find . -type f -name "*.txt"|awk -F_ '{a[$NF]=$0} END{n=asorti(a,b); for(i=1; i<=n; i++) print a[b[i]]}'
./filename2_20230517_055806.txt
./file_name_4_20230517_063806.txt
./filename1_20230517_065806.txt
./filename_3_20230517_125806.txt
© www.soinside.com 2019 - 2024. All rights reserved.