Respostas:
Semelhante à primeira opção, mas omite o delimitador à direita
ls -1 | paste -sd "," -
paste
recebe -
(entrada padrão) como padrão, pelo menos no meu paste (GNU coreutils) 8.22
.
"\0"
, então paste -sd "\0" -
funcionou para mim!
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"
\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
depois tr
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 -1 | tr '\n' ',' | sed 's/,$/\n/'
ls -m
inclui novas linhas no caractere de largura da tela (80º por exemplo).
Principalmente Bash (apenas ls
externo):
saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS
Usando readarray
(aka mapfile
) no Bash 4:
readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS
Obrigado a gniourf_gniourf pelas sugestões.
mapfile
(Bash ≥4) como: mapfile -t files < <(ls -1)
. Não há necessidade de mexer IFS
. 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
ls -1 | awk 'ORS=","'
O ORS é o "separador de registros de saída", agora suas linhas serão unidas por uma vírgula.
" 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 shell
(set -- *; IFS=,; echo "$*")
Para capturar a saída,
output=$(set -- *; IFS=,; echo "$*")
set
funciona? Parece um pouco de vodu para mim. Um olhar superficial man 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 proteger set
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 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[*]}" )
type set
vou lhe dizer set is a shell builtin
,. Então, man set
não vai ajudar, mas help 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 é usar find
, por exemplo:
find . -type f -print0 | tr '\0' ','
Ou usando find
e paste
:
find . -type f | paste -d, -s
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 .
Não reinvente a roda.
ls -m
Faz exatamente isso.
ls -m
e tr
para remover o espaço após a vírgula que você farials -m | tr -d ' '
sed 's/, /,/g
apenas bater
mystring=$(printf "%s|" *)
echo ${mystring%|}
|
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:
ls -1 | perl -l40pe0
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 ''
Parece que as respostas já existem.
Se você deseja
a, b, c
formatar, use ls -m
( resposta de Tulains Córdova )
Ou, se você deseja a b c
formatar, use ls | xargs
(versão simplificada da resposta de Chris J )
Ou se você quiser qualquer outro delimitador como |
, use ls | paste -sd'|'
(aplicação da resposta de Artem )
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 ghead
um número de bytes negativo, ou melhor, criar um alias:
alias head="ghead"
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 1 100000 | sed ':a; N; $!ba; s/\n/,/g' | head -c 80
# linear, in less than 0.1s
seq 1 100000 | sed ':a; /$/N; s/\n/,/; ta' | head -c 80
# quadratic, hung
Se a sua versão do xargs suportar o sinalizador -d, isso funcionará
ls | xargs -d, -L 1 echo
-d é o sinalizador delimitador
Se você não possui -d, tente o seguinte
ls | xargs -I {} echo {}, | xargs echo
O primeiro xargs permite que você especifique seu delimitador, que é uma vírgula neste exemplo.
-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.
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
Retirado do meu blog .
Você pode usar:
ls -1 | perl -pe 's/\n$/some_delimiter/'
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:
ls | perl -F'\n' -0777 -anE 'say join ",", @F'
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
ls | sed '$!s/$/,/' | tr -d '\n'
ls
tem a opção -m
de delimitar a saída com ", "
uma vírgula e um espaço.
ls -m | tr -d ' ' | tr ',' ';'
canalizar esse resultado para tr
remover o espaço ou a vírgula permitirá canalizar o resultado novamente tr
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.
Versão Quick Perl com manipulação de barra à direita:
ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'
Explicar:
ls -1 | paste -s -d ":" -
Não tenho certeza se isso é universal com todas as versões do colar