英文:
Sorting the files in a directory by the last delimited substring while displaying the original file name
问题
Sure, here is the translated code portion:
我有一个包含以时间戳结尾的文件的目录。我想按文件名中的时间戳顺序迭代这个目录中的文件。我在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...
有办法让sort命令查看最后一个分隔的索引并根据它进行排序吗?
Please note that the translation is provided only for the code portion, as per your request.
<details>
<summary>英文:</summary>
I have a directory that contains files ending in a timestamp. I would like to iterate through the files in this directory order by that timestamp in the name. I am doing this in a shell script in Unix.
filename1_20230517_065806.txt
filename2_20230517_055806.txt
filename_3_20230517_125806.txt
file_name_4_20230517_063806.txt
I need this to be processed in the following order
filename2_20230517_055806.txt
file_name_4_20230517_063806.txt
filename1_20230517_065806.txt
filename_3_20230517_125806.txt
The order should only be looking at the time section of the file name. I was hoping to do something like this, but since the filed names can have any number of underscores I'm having difficulties.
for i in $(ls *.txt | sort -t'_' -k3)
do...
Is there a way to have sort look at the last delimited index and sort by that?
</details>
# 答案1
**得分**: 1
我认为你需要使用awk来处理这个问题,使用临时增加数据的“技巧”,即在每一行前缀加上所需的排序键。我在下面的排序键中添加了日期($(NF-1))。
```bash
for i in $(ls *.txt | awk -F_ '{print $(NF-1) $NF "\t" $0}' | sort | cut -f 2-)
do...
英文:
I think you’re going to need the help of awk for this, using the “trick” of temporarily augmenting the data by prefixing each line with the desired sort key. I added in the date ($(NF-1)) to the sort key below as well.
for i in $(ls *.txt | awk -F_ ‘{print $(NF-1) $NF “\t” $0}’ | sort | cut -f 2-)
do...
答案2
得分: 1
你可以使用 "rev" 来反转元素,然后根据前两个元素进行排序:
英文:
You can use "rev" to reverse the elements and than sort with the first two elements:
#!/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
The output looks like expected:
filename2_20230517_055806.txt
file_name_4_20230517_063806.txt
filename1_20230517_065806.txt
filename_3_20230517_125806.txt
答案3
得分: 1
$ 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
英文:
$ 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论