Encontre o nome de arquivo com maior número em um diretório em que os nomes começam com dígitos
Pergunta
Eu tenho um diretório com arquivos que se parecem:
001_something.php 002_something_else.php
004_xyz.php 005_do_good_to_others.php
Em última análise, quero criar um novo arquivo PHP vazio cujo nome começa com o próximo número da série.
LIST=`exec ls $MY_DIR | sed 's/\([0-9]\+\).*/\1/g' | tr '\n' ' '`
O código anterior me dá uma string como esta:
LIST='001 002 004 005 '
Quero pegar esse 005, incremento em um e, em seguida, usar esse número para gerar o novo nome do arquivo. Como faço isso em Bash?
Solução
$ LIST=($LIST)
$ newfile=`printf %03d-whatever $((10#${LIST[${#LIST}]}+1))`
$ echo $newfile
006-whatever
Então, isso é específico da festa. Abaixo está a Any-Posix-Shell-Including-Bash Solução, eu imagino que algo mais simples seja possível.
$ 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
$
Outras dicas
Você precisa da lista inteira?
Se não
LAST=`exec ls $MY_DIR | sed 's/\([0-9]\+\).*/\1/g' | sort -n | tail -1`
lhe darei apenas a parte 005 e
printf "%03d" `expr 1 + $LAST`
Imprimirá o próximo número na sequência.
Usando apenas ferramentas padrão, o seguinte fornecerá o prefixo para o novo arquivo (006):
ls [0-9]* | sed 's/_/ _/' | sort -rn | awk '{printf "%03d", $1 + 1; exit}'
Isso parece ser mais simples.
ls [0-9]* | sort -rn | awk '{FS="_"; printf "%03d_new_file.php\n",$1+1;exit}'
Rápido, sem subshell e sem loop (também lida com nomes de arquivos com espaços)*:
list=([0-9]*)
last=${list[@]: -1}
nextnum=00$((10#${last%%[^0-9]*} + 1))
nextnum=${nextnum: -3}
touch ${nextnum}_a_new_file.php
Dados seus arquivos de exemplo, a saída seria:
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
Eu deixo para você fazer a criação de um novo arquivo
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)))
Publico esta resposta para propor uma solução mínima para a questão principal "Encontre o nome de arquivo com maior número em um diretório em que os nomes começam com dígitos":
ls -1 "$MyDir" | sort -hr | head -n 1
A primeira declaração coloca os arquivos no mydir como um revestimento com a opção -1. Isso é canalizado para a função de classificação que classifica em ordem numérica humana com -h e na ordem inversa (número mais alto primeiro) com -r. Isso é canalizado para a função da cabeça, que apenas entrega a maioria dos resultados -n (1 no exemplo). A resposta considera a ordem de classificação numérica humana, ou seja, 221 é superior a 67. É uma solução de shell POSIX tão altamente compatível.
Aqui está uma solução (você precisa de 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