Sorting the files in a directory by the last delimited substring while displaying the original file name

huangapple go评论69阅读模式
英文:

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&#39;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=&quot;filename1_20230517_065806.txt filename2_20230517_055806.txt filename_3_20230517_125806.txt file_name_4_20230517_063806.txt&quot;

# Convert the filenames string into an array
IFS=&#39; &#39; read -r -a files_array &lt;&lt;&lt; &quot;$filenames&quot;

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

for file in &quot;${sorted_array[@]}&quot;; do
  echo &quot;$file&quot;
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 &quot;*.txt&quot;|awk -F_ &#39;{a[$NF]=$0} END{n=asorti(a,b); for(i=1; i&lt;=n; i++) print a[b[i]]}&#39;
./filename2_20230517_055806.txt
./file_name_4_20230517_063806.txt
./filename1_20230517_065806.txt
./filename_3_20230517_125806.txt

huangapple
  • 本文由 发表于 2023年5月18日 05:45:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276404.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定