Liste des Groupes |
On Wed, 19 Jun 2024 16:06:37 +0100, Chris Elvidge <chris@x550c.mshome.net>I didn't realise it could work like that. Thanks.
wrote in <v4us5u$21bu3$1@dont-email.me>:
On 19/06/2024 at 14:11, Janis Papanagnou wrote:I finally remembered which tool has "versionsort(3)" -- it's ls:On 19.06.2024 14:40, Chris Elvidge wrote:Your way is still restricted to filenames with a known number of sets ofOn 18/06/2024 at 18:04, Janis Papanagnou wrote:>I've just tried a Unix tools based solution (with sed, sort, cut).If you're happy not handling pathological filenames:
[...]
[...], and for more than two numeric fields it can be modified to
dynamically construct the sed pattern, the sort option list, and the
cut parameter, once at the beginning; that way we could have a tool
for arbitrary amounts of numeric keys in the file name.
>
Note: this program doesn't handle pathological filenames (newlines).
>
>
Well, typically I can indeed ignore them. But it's better of course to
avoid situations where processing is compromised by such names.
>
>for (( i=1; i<=50; i++ )); do for (( j=2; j<=120; j+=3 )); do touch>
"a${i}b${j}c.txt"; done; done to create the files.
>
exnums() { j="$(sed 's/[^[:digit:]]\+/ /g' <<<"$@")"; printf '%s%s\n'
"$j" "$@"; }
function replaces all non-digit sequences with a space, prints digit
sequence(s) and original input.
>
for i in *; do exnums "$i"; done | sort -k1n -k2n -k3n -k4n | awk
'{print $NF}'
sort doesn't seem to care how many -k you use, fields separated with
space.
awk prints the last field of the input.
>
This "seems" to work with all manner of filenames from PNN.htm (as
your original sequence) to p323dc45g12.htm, p324dc45g12.htm,
p333dc45g12.htm Seems to work in ksh, too.
I tried the approach I outlined above... (here just echo'ing the
created parts)...
>
>
N=${1:-1}
sed_a="[^0-9]*\([0-9]\+\)[^0-9]*"
sed_r="\1\t"
sort_a="-k1n"
for (( n=2; n<=N; n++ ))
do
sed_a+="\([0-9]\+\)[^0-9]*"
sed_r+="\${n}\t" sort_a+=" -k${n}n"
done cut_a="-f$((N+1))-"
>
echo "# The following commands would be connected by pipes:"
echo "sed 's/${sed_a}/${sed_r}&/'"
echo "sort -t$'\t' ${sort_a}"
echo "cut ${cut_a}"
>
>
Janis
>
>
digits, though (AFAICS). I.e. you pass N rather than finding it.
>
But it takes a long time to do it my way, a call to sed for each
filename, so I tried to cut down the time taken to do this and came up
with:
>
bash: exnums() { shopt -s extglob; j="${@//+([^[:digit:]])/ }"; printf
'%s%s\n' "$j" "$@"; }
>
ksh: exnums() { j="${@//+([^[:digit:]])/ }"; printf '%s%s\n' "$j" "$@";
}
>
ksh seems to do the extglob needed for bash natively.
>
removing the sed calls from exnum changes the time taken from 37 secs to
under 1 sec with 2000+ files ksh is faster than bash, ksh 50% of the
bash time taken.
>
Substituting a tab for the replacement space in j= and -t$'\t' in sort
would seem to allow spaces in filenames, too, as you originally had it.
$ ls -1
test10.txt
test1.txt
test2.txt
$ ls -v -1
test1.txt
test2.txt
test10.txt
Does that help?
Les messages affichés proviennent d'usenet.