Enumere arquivos e diretórios com o comando 'ls'

12

Execute o comando ls no diretório atual e obtenha a saída:

$ ls
Applications Documents    Library      Music        Public
Desktop      Downloads    Movies       Pictures

Gostaria de enumerá-los como:

1. Applications
2. Desktop
3. Documents
4. Downloads
5. Library
6. Movies
7. Music
8. Pictures
9. Public

Isso pode ser alcançado usando less de uma maneira intermediária

ls | less -N

Como enumerá-los de maneira direta?

    
por JawSaw 26.03.2018 / 12:57

4 respostas

16

Ou simplesmente faça:

ls -b |nl -s '. ' -w 1
1. a\ file\ with\ nonewline
2. a\ file\ with\nnewline
3. a\ file\ with\ space
4. afile

de man nl :

-s, --number-separator=STRING
              add STRING after (possible) line number
-w, --number-width=NUMBER
              use NUMBER columns for line numbers
    
por devWeek 26.03.2018 / 14:56
13

Você deve enviar a saída de ls para outro comando. Minha sugestão é usar awk em desta forma :

$ ls -b --group-directories-first | awk '{print NR ". " $0}'
1. dir1
2. dir2
3. dir3
4. z-dir1
5. z-dir2
6. z-dir3
7. file1
8. file2
9. file3
10. file4
11. file5
12. file6
13. file7
14. file\nnewline
  • Observe que o arquivo file\nnewline contém o caractere de nova linha \n em seu nome, que é ignorado pela opção -b .

  • a opção --group-directories-first exibirá os diretórios antes dos arquivos.

Outra maneira possível é usar o loop (mas, neste caso, colocar os diretórios no início da lista se tornará mais difícil):

n=1; for i in *; do echo $((n++)). $i; done
    
por pa4080 26.03.2018 / 13:21
11

Se apenas mostrar um número for o caso, você terá várias opções a seguir e também seu less -N way:

$ ls |cat -n
$ ls |nl

Se você quiser numeração de saída personalizada, sugiro usar find e fazer o que quiser:

find . -exec bash -c 'for fnd; do printf "%d. %s\n" "$((++i))" "$fnd"; done ' _ {} +

POSIXly, você faria:

find . -exec sh -c 'for fnd; do i=$((i+1)); printf "%d.\t%s\n" "$i" "$fnd"; done ' _ {} +
    
por devWeek 26.03.2018 / 13:19
3

Você também pode fazer isso com um script curto de Bash:

#!/bin/bash
set -eu
shopt -s nullglob

[ "$#" -eq 0 ] || cd -- "$1"
i=0
for f in *; do
    printf '%d. %s\n' "$((++i))" "${f//$'\n'/^N}"
done |
cat -vt

Você pode até ser chique e preencher o número da linha por mais de 9 resultados:

#!/bin/bash
set -eu
shopt -s nullglob

[ "$#" -eq 0 ] || cd -- "$1"
ls=(*)
pad=${#ls[@]}
pad=${#pad}
i=0
for f in *; do
    printf '%*d. %s\n' "$pad" "$((++i))" "${f//$'\n'/^N}"
done |
cat -vt

Uso

Supondo que você salvou o script como um arquivo executável numbered-ls.sh no diretório de trabalho atual:

./numbered-ls.sh [DIRECTORY]

O argumento DIRECTORY é opcional e é padronizado para o diretório de trabalho atual.

Explicação

  1. Se o script foi invocado com um argumento, altere o diretório de trabalho para o caminho no primeiro argumento.

  2. Corresponde a todas as entradas do diretório de trabalho atual e examine-as. Para cada entrada, incremente um contador e imprima seu valor junto com o nome da entrada. Os caracteres de quebra de linha no nome da entrada são substituídos por ^N .

  3. Canalize a saída por meio de cat -vt para lidar normalmente com nomes de arquivos que contenham caracteres não imprimíveis que o terminal possa interpretar como caracteres de controle.

por David Foerster 26.03.2018 / 21:52