Reputation: 299
I have some files in a UNIX directory:
/opt/apps/testloc $ ls -mn
test_1.txt
test_2.txt
test_11.txt
test_12.txt
test_3.txt
I want to list this with ls
command and I need the output in sorted order based on the numbers at the end of the file name. Say output should be like below.
test_1.txt, test_2.txt, test_3.txt, test_11.txt, test_12.txt
I am not able to get as mentioned. These file names were considered as text and they were sorted as below,
test_11.txt, test_12.txt, test_1.txt, test_2.txt, test_3.txt
My command ls –mn
(I need the output to be in comma separated format so I have used -m
)
I need this to be done to process the files in incremental format in my next process.
Upvotes: 1
Views: 16467
Reputation: 2583
If all the file names contain exactly one _
character, followed by a numeric value, this relatively simple script will sort file names by the numeric field and output them in a ,[space]
separated list (as ls -m
does):
ls -1 *_* | sort -t_ -n -k2 | sed ':0 N;s/\n/, /;t0'
However, if there are multiple _
characters in file names and you want to sort them by the last numeric field (not necessarily the same within the file names, e.g. test_1_3.txt
and test_2.txt
), more complex script is required:
ls -1 *_* |
awk -F '_' '
{
key[gensub(/\..*$/, "", 1, $NF) "a" NR] = NR;
name[NR] = $0;
}
END {
len = asorti(key, keysorted, "@ind_num_asc");
for (i = 1; i < len; i++) {
printf "%s, ", name[key[keysorted[i] ] ];
}
printf "%s\n", name[key[keysorted[len] ] ];
}'
Upvotes: 0
Reputation: 6577
That you require output to be in a specific format tells me that you shouldn't be using ls. Since recursive results aren't required, use a glob.
# Bash or ksh + GNU or other sort that handles NUL delimiters
function sortFiles {
[[ -e $1 ]] || return 1
typeset a x
for x; do
printf '%s %s\0' "${x//[^[:digit:]]}" "$x"
done |
LC_ALL=C sort -nz - | {
while IFS= read -rd '' x; do
a+=("${x#* }")
done
typeset IFS=,
printf '%s\n' "${a[*]}"
}
}
sortFiles *
Upvotes: 1
Reputation: 85785
If you version of sort
can do a version sort
with -V
then:
$ ls | sort -V | awk '{str=str$0", "}END{sub(/, $/,"",str);print str}'
test_1.txt, test_2.txt, test_3.txt, test_11.txt, test_12.txt
If not do:
$ ls | sort -t_ -nk2,2 | awk '{str=str$0","}END{sub(/,$/,"",str);print str}'
test_1.txt, test_2.txt, test_3.txt, test_11.txt, test_12.txt
Upvotes: 2
Reputation: 21
ls -al | sort +4n : List the files in the ascending order of the file-size. i.e sorted by 5th filed and displaying smallest files first.
Upvotes: -1