Como gerar somente nomes de arquivos (com espaços) em ls -Al?

64

Eu deveria ecoar somente nomes de arquivos ou diretórios com esta construção:

ls -Al | while read string
do
...
done

ls -Al output:

drwxr-xr-x  12 s162103  studs         12 march 28 12:49 personal domain
drwxr-xr-x   2 s162103  studs          3 march 28 22:32 public_html
drwxr-xr-x   7 s162103  studs          8 march 28 13:59 WebApplication1

Por exemplo, se eu tentar:

ls -Al | while read string
do
echo "$string" | awk '{print $9}
done

produza apenas arquivos e diretórios sem espaços. Se o arquivo ou diretório tiver espaços como "domínio pessoal", será apenas a palavra "pessoal".

Eu preciso de uma solução muito simples. Talvez haja uma solução melhor que o awk.

    
por Alex Zern 30.03.2013 / 15:59

9 respostas

79

Você realmente não deve analisar a saída de ls . Se esta é uma tarefa de casa e você é obrigado a, seu professor não sabe o que está falando. Por que você não faz algo assim:

O bom ...

find ./  -printf "%f\n"

ou

for n in *; do printf '%s\n' "$n"; done

... o ruim ...

Se você realmente quiser usar ls , você pode torná-lo um pouco mais robusto, fazendo algo parecido com isto:

ls -lA | awk -F':[0-9]* ' '/:/{print $2}'

... e o feio

Se você insistir em fazê-lo da maneira errada e perigosa e apenas usar um while loop, faça isso:

ls -Al | while IFS= read -r string; do echo "$string" | 
    awk -F':[0-9]* ' '/:/{print $2}'; done

Falando sério, apenas não.

    
por 30.03.2013 / 17:11
62

Existe algum motivo para que ls -A1 * não funcione?

Por exemplo:

$ touch file1 file2 file\ with\ spaces
$ ls -Al
total 0
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file1
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file2
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file with spaces
$ ls -A1
file1
file2
file with spaces
$

* Nota: é uma letra maiúscula A e a número um.

    
por 31.03.2013 / 07:35
31

Eu me pergunto por que ninguém mencionou este comando simples:

ls -a | sort
    
por 11.08.2016 / 10:14
3

Você não pode analisar a saída de ls , e muito menos ls -l porque nova linha, assim como o espaço é tão válido quanto qualquer caractere em um nome de arquivo. Além disso, você precisará considerar links simbólicos que tenham uma saída como ... foo -> bar .

Por que você usaria -l de qualquer maneira se quiser apenas o nome do arquivo?

Basta fazer:

for file in *; do
  ...
done

Se você quiser incluir arquivos de ponto (exceto . e .. ), dependendo do shell:

zsh :

for file in *(ND); do
  ...
done

bash :

shopt -s nullglob dotglob
for file in *; do
  ...
done

ksh93 :

FIGNORE='@(.|..)'
for file in ~(N)*; do
  ...
done

POSIXly:

for file in .[!.]* ..?* *; do
  [ -e "$file" ] || [ -L "$file" ] || continue
  ...
done
    
por 10.04.2015 / 21:24
1

Que tal:

for file in * .[!.]*
do
  printf "%s\n" "$file"
done
    
por 30.03.2013 / 17:13
1
ls -Al | tr -s ' ' | cut -f9- -d' '

compacta vários espaços em espaços simples com tr, então você pode usar o corte para dividir nos campos

    
por 04.03.2015 / 22:16
1

Experimente ( bash , zsh , ksh93 syntax):

find . -type f -print0 | while IFS= read -r -d '' filename; do
  ...
done

This goes recursive and lists only on normal files (i.e. no dirs or symlinks/fifos/devices...).

Veja também:

por 04.03.2015 / 19:01
0

tente ls -1 Isso é um inteiro 1

Da página man.

     ls -1     list one file per line.  Avoid '\n' with -q or -b
    
por 02.12.2018 / 09:30
-1
ls --file *|grep ^ 

exibe quais arquivos sob qual diretório.

    
por 25.12.2016 / 20:21