Apenas como uma observação, a versão da pasta que eu tentei requer um argumento "-" no final para dizer para ler em STDIN. eg ls -1 | paste -s -d ":" - Não tenho certeza se isso é universal com todas as versões do colar
Andy White
4
este é melhor porque permite delimitador vazio :)
Yura Purbeev
2
Nota pasterecebe -(entrada padrão) como padrão, pelo menos no meu paste (GNU coreutils) 8.22.
fedorqui 'Então, pare de prejudicar'
1
Acabei de votar, este é e agora tem os mesmos votos que a resposta selecionada. ESTA É A RESPOSTA. nenhum delimitador à direita
thebugfinder 14/15
1
O delimitador vazio pode ser especificado usando "\0", então paste -sd "\0" -funcionou para mim!
Brad Parks
378
EDIT : Simplesmente " ls -m " Se você quiser que seu delimitador seja uma vírgula
Ah, o poder e a simplicidade!
ls -1| tr '\n'','
Mude a vírgula " , " para o que quiser. Observe que isso inclui uma "vírgula à direita"
Isso não cuidará dos arquivos com espaços em branco no nome. Tente este: dir = / tmp / testdir; rm -rf $ dir && mkdir $ dir && cd / $ dir && touch "este é um arquivo" this_is_another_file && ls -1 && files = ($ (ls -1)) && list = $ {files [@] /% / ,} && list = $ {list% *,} && echo $ list
dimir
1
@dimir: Muitas das respostas a esta pergunta sofrem com esse problema. Editei minha resposta para permitir nomes de arquivos com guias ou espaços, mas não novas linhas.
Pausado até novo aviso.
Sua versão do bash também sofre com expansões de nome de caminho. Para construir uma matriz de linhas, por favor, considere usar mapfile(Bash ≥4) como: mapfile -t files < <(ls -1). Não há necessidade de mexer IFS. E é mais curto também.
gniourf_gniourf
E quando você tem sua matriz, você pode usar IFSpara se juntar aos campos: saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS. Ou use outro método se desejar um separador com mais de um caractere.
gniourf_gniourf
1
@gniourf_gniourf: incluí suas sugestões na minha resposta. Obrigado.
Pausado até novo aviso.
24
Eu acho que este é incrível
ls -1| awk 'ORS=","'
O ORS é o "separador de registros de saída", agora suas linhas serão unidas por uma vírgula.
Você tem mais algumas informações sobre como setfunciona? Parece um pouco de vodu para mim. Um olhar superficial man settambém não me deu muita informação.
Ehtesh Choudhury
3
Se você fornecer setvários argumentos, mas nenhuma opção, ele definirá os parâmetros posicionais ($ 1, $ 2, ...). --existe para proteger setno caso de o primeiro argumento (ou nome do arquivo neste caso) começar com um traço. Veja a descrição da --opção em help set. Acho os parâmetros posicionais uma maneira conveniente de lidar com uma lista de coisas. Eu também poderia ter implementado este com uma matriz:output=$( files=(*); IFS=,; echo "${files[*]}" )
Glenn Jackman
Isso é ótimo, pois não requer a execução de nenhum programa adicional e funciona com nomes de arquivos que contêm espaços ou até novas linhas.
Eric
1
@EhteshChoudhury Como type setvou lhe dizer set is a shell builtin,. Então, man setnão vai ajudar, mas help setvai ajudar. Resposta: "- Atribua os argumentos restantes aos parâmetros posicionais."
Stéphane Gourichon 30/03/16
Depois de um set -- *. Retardando a expansão de *um nível você pode obter a saída correta, sem a necessidade de um sub shell: IFS=',' eval echo '"$*"'. Claro que isso mudará os parâmetros posicionais.
Isaac
13
A análise lsem geral não é recomendada ; portanto, a melhor maneira alternativa é usar find, por exemplo:
O OP queria qualquer delimitador para que você ainda precisasse de um tr para converter as vírgulas. Ele também adiciona um espaço após a vírgula ou seja file1, file2, file3
Rob
portanto, usando ls -me trpara remover o espaço após a vírgula que você farials -m | tr -d ' '
Andy
2
esse uso de tr excluirá espaços dentro de nomes de arquivos. melhor usarsed 's/, /,/g
Adicionando além da resposta de majkinetor, aqui está a maneira de remover o delimitador à direita (já que ainda não posso comentar com a resposta dele):
ls -1| awk 'ORS=","'| head -c -1
Apenas remova quantos bytes à direita o seu delimitador conta.
Eu gosto dessa abordagem porque posso usar delimitadores de vários caracteres + outros benefícios de awk:
ls -1| awk 'ORS=", "'| head -c -2
EDITAR
Como Peter notou, a contagem de bytes negativos não é suportada na versão nativa do MacOS do cabeçalho. No entanto, isso pode ser facilmente corrigido.
Primeiro instale coreutils. "Os GNU Core Utilities são os utilitários básicos de arquivo, shell e manipulação de texto do sistema operacional GNU."
brew install coreutils
Os comandos também fornecidos pelo MacOS são instalados com o prefixo "g". Por exemplo gls.
Depois de fazer isso, você pode usar gheadum número de bytes negativo, ou melhor, criar um alias:
Nota: contagens negativas de bytes são suportadas apenas em determinadas versões do cabeçote, portanto, isso não funcionará, por exemplo, em macos.
Peter Peter
Obrigado por apontar isso. Eu adicionei uma solução alternativa para o MacOS.
Aleksander Stelmaczonek 6/02/19
4
O caminho sed,
sed -e ':a; N; $!ba; s/\n/,/g'# :a # label called 'a'# N # append next line into Pattern Space (see info sed)# $!ba # if it's the last line ($) do not (!) jump to (b) label :a (a) - break loop# s/\n/,/g # any substitution you want
Nota :
Isso é linear em complexidade, substituindo apenas uma vez depois que todas as linhas são anexadas ao Espaço Padrão do sed.
A resposta de @ AnandRajaseka , e algumas outras respostas semelhantes, como aqui , são O (n²), porque o sed precisa substituir sempre que uma nova linha é anexada ao Espaço Padrão.
Comparar,
seq 1100000| sed ':a; N; $!ba; s/\n/,/g'| head -c 80# linear, in less than 0.1s
seq 1100000| sed ':a; /$/N; s/\n/,/; ta'| head -c 80# quadratic, hung
-despecifica o delimitador de entrada com GNU xargs, portanto não funcionará. O segundo exemplo exibe o mesmo problema que outras soluções aqui de um delimitador perdido no final.
Thor
3
sed -e :a -e '/$/N; s/\n/\\n/; ta'[filename]
Explicação:
-e- indica um comando a ser executado :a- é um rótulo /$/N- define o escopo da correspondência para a atual e a linha ext (N) s/\n/\\n/;- substitui todos os EOL por \n ta;- goto rótulo a se a correspondência for bem-sucedida
lstem a opção -mde delimitar a saída com ", "uma vírgula e um espaço.
ls -m | tr -d ' '| tr ','';'
canalizar esse resultado para trremover o espaço ou a vírgula permitirá canalizar o resultado novamente trpara substituir o delimitador.
no meu exemplo, substituo o delimitador ,pelo delimitador;
substitua ;por qualquer delimitador de um caractere que você preferir, pois tr considera apenas o primeiro caractere nas cadeias de caracteres que você transmite como argumentos.
ls -1 | paste -s -d ":" -
Não tenho certeza se isso é universal com todas as versões do colarpaste
recebe-
(entrada padrão) como padrão, pelo menos no meupaste (GNU coreutils) 8.22
."\0"
, entãopaste -sd "\0" -
funcionou para mim!Ah, o poder e a simplicidade!
Mude a vírgula " , " para o que quiser. Observe que isso inclui uma "vírgula à direita"
fonte
\n
, isso também será substituído.ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sed
poderia ser um pouco mais eficiente com o caractere de marcador final:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sed
depoistr
parece apenas remover o último símbolo não parece razoável. Eu vou comls -1 | tr '\n' ',' | head -c -1
Isso substitui a última vírgula por uma nova linha:
ls -m
inclui novas linhas no caractere de largura da tela (80º por exemplo).Principalmente Bash (apenas
ls
externo):Usando
readarray
(akamapfile
) no Bash 4:Obrigado a gniourf_gniourf pelas sugestões.
fonte
mapfile
(Bash ≥4) como:mapfile -t files < <(ls -1)
. Não há necessidade de mexerIFS
. E é mais curto também.IFS
para se juntar aos campos:saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS
. Ou use outro método se desejar um separador com mais de um caractere.Eu acho que este é incrível
O ORS é o "separador de registros de saída", agora suas linhas serão unidas por uma vírgula.
fonte
" OR "
)A combinação de configuração
IFS
e uso de"$*"
pode fazer o que você deseja. Estou usando um subshell para não interferir no $ IFS deste shellPara capturar a saída,
fonte
set
funciona? Parece um pouco de vodu para mim. Um olhar superficialman set
também não me deu muita informação.set
vários argumentos, mas nenhuma opção, ele definirá os parâmetros posicionais ($ 1, $ 2, ...).--
existe para protegerset
no caso de o primeiro argumento (ou nome do arquivo neste caso) começar com um traço. Veja a descrição da--
opção emhelp set
. Acho os parâmetros posicionais uma maneira conveniente de lidar com uma lista de coisas. Eu também poderia ter implementado este com uma matriz:output=$( files=(*); IFS=,; echo "${files[*]}" )
type set
vou lhe dizerset is a shell builtin
,. Então,man set
não vai ajudar, mashelp set
vai ajudar. Resposta: "- Atribua os argumentos restantes aos parâmetros posicionais."set -- *
. Retardando a expansão de*
um nível você pode obter a saída correta, sem a necessidade de um sub shell:IFS=',' eval echo '"$*"'
. Claro que isso mudará os parâmetros posicionais.A análise
ls
em geral não é recomendada ; portanto, a melhor maneira alternativa é usarfind
, por exemplo:Ou usando
find
epaste
:Para ingressar em várias linhas de maneira geral (não relacionadas ao sistema de arquivos), verifique: “Junção” concisa e portátil na linha de comando do Unix .
fonte
Não reinvente a roda.
Faz exatamente isso.
fonte
ls -m
etr
para remover o espaço após a vírgula que você farials -m | tr -d ' '
sed 's/, /,/g
apenas bater
fonte
|
mastiga a trilha, @camh.bash
e gnu coreutilsprintf
printf -v
funcionará apenas no bash, enquanto a resposta apresentada funciona em muitos tipos de shell.|
, desde que ambas as linhas são utilizadas:printf -v mystring "%s|" * ; echo ${mystring%|}
.Este comando é para os fãs do PERL:
Aqui 40 é o código ASCII octal para o espaço.
-p processará linha por linha e imprimirá
-l cuidará de substituir o \ n final pelo caractere ascii que fornecemos.
-e é informar PERL que estamos executando a linha de comando.
0 significa que não há realmente nenhum comando para executar.
perl -e0 é o mesmo que perl -e ''
fonte
Para evitar possíveis confusões de nova linha para tr, podemos adicionar o sinalizador -b a ls:
fonte
Parece que as respostas já existem.
Se você deseja
a, b, c
formatar, usels -m
( resposta de Tulains Córdova )Ou, se você deseja
a b c
formatar, usels | xargs
(versão simplificada da resposta de Chris J )Ou se você quiser qualquer outro delimitador como
|
, usels | paste -sd'|'
(aplicação da resposta de Artem )fonte
Adicionando além da resposta de majkinetor, aqui está a maneira de remover o delimitador à direita (já que ainda não posso comentar com a resposta dele):
Apenas remova quantos bytes à direita o seu delimitador conta.
Eu gosto dessa abordagem porque posso usar delimitadores de vários caracteres + outros benefícios de
awk
:EDITAR
Como Peter notou, a contagem de bytes negativos não é suportada na versão nativa do MacOS do cabeçalho. No entanto, isso pode ser facilmente corrigido.
Primeiro instale
coreutils
. "Os GNU Core Utilities são os utilitários básicos de arquivo, shell e manipulação de texto do sistema operacional GNU."Os comandos também fornecidos pelo MacOS são instalados com o prefixo "g". Por exemplo
gls
.Depois de fazer isso, você pode usar
ghead
um número de bytes negativo, ou melhor, criar um alias:fonte
O caminho sed,
Nota :
Isso é linear em complexidade, substituindo apenas uma vez depois que todas as linhas são anexadas ao Espaço Padrão do sed.
A resposta de @ AnandRajaseka , e algumas outras respostas semelhantes, como aqui , são O (n²), porque o sed precisa substituir sempre que uma nova linha é anexada ao Espaço Padrão.
Comparar,
fonte
Se a sua versão do xargs suportar o sinalizador -d, isso funcionará
-d é o sinalizador delimitador
Se você não possui -d, tente o seguinte
O primeiro xargs permite que você especifique seu delimitador, que é uma vírgula neste exemplo.
fonte
-d
especifica o delimitador de entrada com GNU xargs, portanto não funcionará. O segundo exemplo exibe o mesmo problema que outras soluções aqui de um delimitador perdido no final.Explicação:
-e
- indica um comando a ser executado:a
- é um rótulo/$/N
- define o escopo da correspondência para a atual e a linha ext (N)s/\n/\\n/;
- substitui todos os EOL por\n
ta;
- goto rótulo a se a correspondência for bem-sucedidaRetirado do meu blog .
fonte
Você pode usar:
fonte
ls
produz uma saída de coluna quando conectado a um tubo, portanto-1
é redundante.Aqui está outra resposta perl usando a
join
função embutida que não deixa um delimitador à direita:O obscuro
-0777
faz com que o perl leia toda a entrada antes de executar o programa.alternativa sed que não deixa um delimitador à direita
fonte
ls
tem a opção-m
de delimitar a saída com", "
uma vírgula e um espaço.canalizar esse resultado para
tr
remover o espaço ou a vírgula permitirá canalizar o resultado novamentetr
para substituir o delimitador.no meu exemplo, substituo o delimitador
,
pelo delimitador;
substitua
;
por qualquer delimitador de um caractere que você preferir, pois tr considera apenas o primeiro caractere nas cadeias de caracteres que você transmite como argumentos.fonte
Você pode usar chomp para mesclar várias linhas em uma única linha:
perl -e 'while (<>) {if (/ \ $ /) {chomp; } print;} 'bad0> test
Coloque a condição de quebra de linha na instrução if.Pode ser um caractere especial ou qualquer delimitador.
fonte
Versão Quick Perl com manipulação de barra à direita:
Explicar:
fonte