Como posso concatenar uma única coluna de saída em uma lista?

3

Estou usando:

ls /proc | grep -v "^[0-9].*"

para obter uma lista de todos os arquivos e diretórios em / proc que não começam com números. A saída é uma lista de coluna única, ou seja:

acpi
asound
buddyinfo
bus

Como posso fazer disso uma lista de várias colunas ou de itens, por exemplo:

acpi asound buddyinfo bus

ou

acpi,asound,buddyinfo,bus

Eu tentei:

$ ls /proc | grep -v "^[0-9].*" | column -c5

mas ainda tem 1 coluna.

    
por Michael Durrant 11.09.2013 / 14:24

5 respostas

5

Use xargs :

$ command ls /proc | grep -v "^[0-9].*" | xargs

A parte command é necessária porque, se o seu ls tiver alias para ls --color , por exemplo, ele adicionará sequências de escape não imprimíveis à sua saída, que grep procura e produz resultados indesejáveis.

Outras opções

Se você não se importar com a PWD de alteração:

$ cd /proc && echo [^0-9]*

Se você não quiser alterar seu PWD :

$ pushd . &>/dev/null && cd /proc && echo [^0-9]* && popd &>/dev/null

Ou:

$ echo /proc/[^0-9]* | sed 's!/proc/!!g'
    
por 11.09.2013 / 14:27
3

Uma longa lista

Usando o grep

Você pode usar a expansão de shell em /proc e canalizá-la para grep :

$ echo /proc/* | grep -oP "(?<=/proc/)\D.*? " | paste -s -d ''

Exemplo

$ echo /proc/* | grep -oP "(?<=/proc/)\D.*? " | paste -s -d ''
acpi asound buddyinfo bus cgroups ....

O recurso acima faz uso da capacidade de grep de usar o mecanismo de expressões regulares (PCRE) do Perl. É a -P que muda para grep . O -o informa grep para retornar apenas as sequências que correspondem ao padrão. Nós então fazemos uso da habilidade do Perl de olhar para trás. Então, quando encontramos uma string que possui /proc , nós cuidamos do /proc para qualquer string que não comece com um dígito ( \D ). Estas são as cadeias que são retornadas (as iniciais não de dígitos).

A pasta faz algumas limpezas para nós removendo todos os caracteres de nova linha que o grep adicionou ao começar a exibir seus resultados.

Usando sed

Uma alternativa para esse método seria usar sed (ei isso rima).

$ echo /proc/* | sed 's@/proc/[0-9]\+ @@g;s@/proc/@@g'

Esta abordagem encontra todas as strings começando com /proc/ & dígitos & um espaço e substitui-los com nada, efetivamente excluí-los. Depois disso, fazemos outro comando sed , que faz o mesmo com as sequências /proc/ , e ficamos com apenas as sequências iniciais não dígitos.

Várias colunas

Para "agrupar" a saída em colunas, o comando paste faz isso com bastante facilidade. Aqui estou fazendo 2 colunas, mas você pode alterar o comando paste para gerar mais ou menos adicionando traços adicionais ( - ). O column -t no final força a saída a alinhar nas colunas.

$ ls /proc | grep -v "^[0-9].*" | paste - - | column -t

Exemplo

Primeiras 5 linhas de saída graças ao head -5 .

$ ls /proc | grep -v "^[0-9].*" | paste - - |column -t | head -5
acpi           asound
buddyinfo      bus
cgroups        cmdline
cpuinfo        crypto
devices        diskstats

Aqui está a mesma coisa com 4 colunas:

$ ls /proc | grep -v "^[0-9].*" | paste - - - - |column -t | head -5
acpi           asound         buddyinfo     bus
cgroups        cmdline        cpuinfo       crypto
devices        diskstats      dma           dri
driver         execdomains    fb            filesystems
fs             interrupts     iomem         ioports

OBSERVAÇÃO: Per @ JosephR., se você encontrar algum problema com os comandos acima que estão analisando a saída de ls , poderá prefixá-lo com o comando Bash, command , que irá ignorar quaisquer aliases que você possa ter em vigor para ls .

Exemplo

$ command ls /proc | grep -v "^[0-9].*" | paste - - - - |column -t | head -5
acpi           asound         buddyinfo     bus
cgroups        cmdline        cpuinfo       crypto
devices        diskstats      dma           dri
driver         execdomains    fb            filesystems
fs             interrupts     iomem         ioports
    
por 11.09.2013 / 14:46
1

Que tal

ls /proc | grep -v "^[0-9].*" | perl -pe 's/\n/,/'
    
por 11.09.2013 / 14:36
1

Que tal tirar proveito da divisão de palavras baseada em IFS do bash em conjunto com a substituição de comando (assumindo o padrão IFS )

echo $(ls /proc | grep -v "^[0-9].*")
acpi buddyinfo bus cmdline cpuinfo.....
    
por 11.09.2013 / 18:09
1

ls exibe apenas sua saída em colunas quando está imprimindo em um terminal. Quando sua saída é um arquivo ou um pipe, ls imprime um item por linha.

Você pode usar a opção -C para imprimir em colunas, independentemente do tipo de fluxo de saída, mas isso tornará impossível (ou pelo menos difícil) filtrar a saída com grep .

Você pode dizer a ls para ignorar arquivos cujo nome comece com um dígito. Esta é a maneira mais simples de obter saída, que é como a saída de ls /proc somente sem os diretórios do processo.

ls -I '[0-9]*'

Como alternativa, você pode especificar as entradas que deseja listar.

(cd /proc && ls -d [!0-9]*)

Se você quiser apenas as entradas e não se importar com apresentações ou cores, use curingas de shell em vez de ls . O segundo comando é específico para zsh.

(cd /proc && echo [!0-9]*)
echo /proc/[^0-9]*(:t)
    
por 12.09.2013 / 02:12

Tags