Encuentre el nombre de archivo más alto en un directorio donde los nombres comienzan con dígitos

StackOverflow https://stackoverflow.com/questions/1587059

  •  22-09-2019
  •  | 
  •  

Pregunta

Tengo un directorio con archivos que se ven así:

001_something.php  002_something_else.php
004_xyz.php        005_do_good_to_others.php

En última instancia, quiero crear un archivo PHP nuevo y vacío cuyo nombre comience con el siguiente número de la serie.

LIST=`exec ls $MY_DIR | sed 's/\([0-9]\+\).*/\1/g' | tr '\n' ' '`

El código anterior me da una cadena como esta:

LIST='001 002 004 005 '

Quiero obtener ese 005, incrementar por uno y luego usar ese número para generar el nuevo nombre de archivo. ¿Cómo hago eso en Bash?

¿Fue útil?

Solución

$ LIST=($LIST)
$ newfile=`printf %03d-whatever $((10#${LIST[${#LIST}]}+1))`
$ echo $newfile
006-whatever

Entonces, eso es específico de Bash. A continuación se muestra un Anyosx-shell incluye a Solución, aunque imagino que es posible algo más simple.

$ cat /tmp/z
f () {
    eval echo \${$#} | sed -e 's/^0*//'
}
LIST='001 002 004 005 '
newname=`printf %03d-whatever $(($(f $LIST) + 1))`
echo $newname
$ sh /tmp/z
006-whatever
$ 

Otros consejos

¿Necesita toda la lista?

Que no

LAST=`exec ls $MY_DIR | sed 's/\([0-9]\+\).*/\1/g' | sort -n | tail -1`

te dará solo la parte 005 y

printf "%03d" `expr 1 + $LAST`

Imprimirá el siguiente número en la secuencia.

Usando solo herramientas estándar, lo siguiente le dará el prefijo para el nuevo archivo (006):

ls [0-9]* | sed 's/_/ _/' | sort -rn | awk '{printf "%03d", $1 + 1; exit}'

This seems to be more simple.

ls [0-9]* | sort -rn | awk '{FS="_"; printf "%03d_new_file.php\n",$1+1;exit}'

Fast, subshell-free and loop-free (also handles filenames with spaces)*:

list=([0-9]*)
last=${list[@]: -1}
nextnum=00$((10#${last%%[^0-9]*} + 1))
nextnum=${nextnum: -3}
touch ${nextnum}_a_new_file.php

Given your example files the output would be:

006_a_new_file.php
$ for file in *php; do last=${file%%_*} ; done
$ newfilename="test.php"
$ printf "%03d_%s" $((last+1)) $newfilename
006_test.php

i leave it to you to do the creation of new file

  1. touch "newfile_$(printf "%03d" $(echo $(ls 00?_*.php|sed 's/_.*//'|sort -rn|head -1)+1|bc))"
    

    2.

    num=$(ls 00?*.php|sed 's/.*//'|sort -rn|head -1) 
    touch $(printf "newfile_%03d" $((num+1)))

I post this answer to propose a minimal solution to the core question "Find highest numbered filename in a directory where names start with digits":

ls -1 "$MyDir" | sort -hr | head -n 1

The first statement puts out the files in MyDir as one liners with the -1 option. This is piped to the sort function which sorts in human numeric order with -h and in reverse order (highest number first) with -r. This is piped to the head function which just delivers the -n top most results (1 in the example). The answer considers human numeric sort order i.e. 221 is higher than 67. It is a POSIX shell solution so highly compatible.

Here's a solution (you need bc):

#!/bin/bash

LIST='001 002 008 005 004 002 '
a=0

for f in $LIST
do
    t=$(echo $f + 1|bc)
    if [ $t -ge $a ]
    then
        a=$t
    fi
done

printf "%03d\n" $a
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top