Existem muitas maneiras de fazer isso. Por exemplo, se você tiver certeza de que os nomes dos arquivos não contêm novas linhas, faça o seguinte:
$ ls | cat -n
1 a.sh
2 b.sh
3 c.sh
4 d.sh
Uma maneira mais segura de lidar com nomes de arquivos que contêm novas linhas ou outros caracteres estranhos:
$ c=0; for file in *; do ((c++)); printf '%s : %s\n' "$c" "$file"; done
1 : a.sh
2 : b.sh
3 : c.sh
4 : d.sh
Para ver porque os dois últimos são melhores, crie um nome de arquivo que contenha novas linhas:
$ touch 'a long file name'
$ touch 'another long filename, this one has'$'\n''a newline character!'
Agora, compare a saída das duas abordagens:
$ ls | cat -n
1 a long file name
2 another long filename, this one has
3 a newline character!
4 a.sh
5 b.sh
6 c.sh
7 d.sh
Como você pode ver acima, parsing ls
(que geralmente é uma má idéia) resulta no nome do arquivo com a nova linha sendo tratada como dois arquivos separados. A saída correta é:
$ c=0; for file in *; do ((c++)); printf '%s : %s\n' "$c" "$file"; done
1 : a long file name
2 : another long filename, this one has
a newline character!
3 : a.sh
4 : b.sh
5 : c.sh
6 : d.sh
Como @Vikyboss aponta nos comentários, a solução de shell acima definirá a variável $c
, que persistirá após a saída do loop. Para evitar isso, você pode adicionar unset c
no final ou usar outra abordagem. Por exemplo:
$ perl -le 'for(0..$#ARGV){print $_+1 ." : $ARGV[$_]"}' *
1 : a long file name
2 : another long filename, this one has
a newline character!
3 : a.sh
4 : b.sh
5 : c.sh
6 : d.sh