Eu tenho dois arquivos de texto. O primeiro tem conteúdo:
Languages
Recursively enumerable
Regular
enquanto o segundo tem conteúdo:
Minimal automaton
Turing machine
Finite
Eu quero combiná-los em um arquivo em colunas. Então eu tentei paste 1 2
e sua saída é:
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
No entanto, eu gostaria de ter as colunas bem alinhadas, como
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Eu queria saber se seria possível conseguir isso sem manusear manualmente?
Adicionado:
Aqui está outro exemplo, em que o método Bruce quase o prende, exceto por um leve desalinhamento sobre o qual me pergunto por quê?
$ cat 1
Chomsky hierarchy
Type-0
—
$ cat 2
Grammars
Unrestricted
$ paste 1 2 | pr -t -e20
Chomsky hierarchy Grammars
Type-0 Unrestricted
— (no common name)
pr
eexpand
...columns
evita esse problema.➀ unicode may render oddly
but the column count is ok
definitivamente não se aplicamwc-paste-pr
ewc-paste-pr
eles mostram diferenças na contagem de colunas. Os outros estão ok.pr
do multibyte caracteres no código do idioma atual (geralmente UTF8).Respostas:
Você só precisa do
column
comando e diz para ele usar guias para separar colunasPara resolver a controvérsia da "célula vazia", precisamos apenas da
-n
opção decolumn
:A página de manual da minha coluna indica que
-n
é uma "extensão Debian GNU / Linux". Meu sistema Fedora não exibe o problema de células vazias: parece derivado do BSD e a página do manual diz "A versão 2.23 mudou a opção -s para não ser gananciosa"fonte
column
claro; quão óbvio (em retrospecto) +1 ... Obrigado ...column -s $'\t' -t
ignora células vazias , resultando em todas as células subsequentes à direita (nessa linha) para mover para a esquerda; ou seja, como resultado de uma linha em branco em um arquivo, ou sendo mais curto ... :(Você está procurando o prático
pr
comando dandy :O "-e24" é "a tab de expansão para 24 espaços". Felizmente,
paste
coloca um caractere de tabulação entre as colunas, parapr
expandi-lo. Eu escolhi 24 contando os caracteres em "Recursivamente enumerável" e adicionando 2.fonte
expand
comando diretamentepaste file1 file2 | expand -t 24
:?sed
então há um processo que não é executado. Ele usapr
um comando antigo, datado dos dias Unix SysV, eu acho, para que possa existir em mais instalações queexpand
. É apenas a velha escola, em suma.Atualização : Aqui está um script muito mais simples (aquele no final da pergunta) para saída tabulada. Basta passar o nome do arquivo para ele como você faria
paste
... Ele é usadohtml
para criar o quadro, para que seja ajustado. Ele preserva vários espaços e o alinhamento da coluna é preservado quando encontra caracteres unicode. No entanto, a maneira como o editor ou visualizador renderiza o unicode é outra questão inteiramente ...---
Uma sinopse das ferramentas apresentadas nas respostas (até agora).
Eu olhei bem de perto para eles; aqui está o que eu encontrei:
paste
# Esta ferramenta é comum a todas as respostas apresentadas até o momento # Ela pode lidar com vários arquivos; portanto, várias colunas ... Bom! # Delimita cada coluna com uma guia ... Bom. # Sua saída não é tabulada.Todas as ferramentas abaixo removem este delimitador! ... Ruim, se você precisar de um delimitador.
column
# Ele remove o delimitador de tabulação, para que a identificação do campo seja puramente feita por colunas que parecem funcionar muito bem .. Não vi nada errado ... # Além de não ter um delimitador exclusivo, ele funciona bem!expand
# Apenas possui uma configuração de guia única, portanto é imprevisível além de 2 colunas # O alinhamento das colunas não é preciso ao manipular unicode e remove o delimitador de tabulação, para que a identificação do campo seja puramente pelo alinhamento da colunapr
# Apenas possui uma configuração de guia única, portanto é imprevisível além de 2 colunas. # O alinhamento das colunas não é preciso ao manipular o unicode e remove o delimitador de tabulação, portanto a identificação do campo é puramente pelo alinhamento da colunaPara mim,
column
é a melhor solução óbvia como uma linha. Você deseja que o delimitador ou uma tablatura de seus arquivos, conforme a arte ASCII, continue lendo, caso contrário ...columns
é muito bom :)Aqui está um script que pega qualquer número de arquivos e cria uma apresentação tabulada da arte ASCII. (Lembre-se de que o unicode pode não renderizar na largura esperada, por exemplo, ௵ que é um único caractere. Isso é bem diferente da coluna os números estão errados, como é o caso em alguns dos utilitários mencionados acima.) ... A saída do script, mostrada abaixo, é de 4 arquivos de entrada, chamados F1 F2 F3 F4 ...
Aqui está a minha resposta original (aparada um pouco no lugar do script acima)
Usando
wc
para obter a largura da coluna esed
para o teclado direito com um caractere visível.
(apenas para este exemplo) ... e depoispaste
juntar as duas colunas com um caractere Tab ...Se você deseja preencher a coluna da direita:
fonte
Você está quase lá.
paste
coloca um caractere de tabulação entre cada coluna; portanto, tudo que você precisa fazer é expandir as tabs. (Presumo que seus arquivos não contenham guias.) Você precisa determinar a largura da coluna esquerda. Com os utilitários GNU (recentes o suficiente),wc -L
mostra o comprimento da linha mais longa. Em outros sistemas, faça uma primeira passagem com awk. A+1
é a quantidade de espaço em branco que você deseja entre as colunas.Se você possui o utilitário de coluna BSD, pode usá-lo para determinar a largura da coluna e expandir as guias de uma só vez. (
␉
é um caractere de tabulação literal; em bash / ksh / zsh você pode usar em$'\t'
vez disso, e em qualquer shell que pode usar"$(printf '\t')"
.)fonte
wc
, o comando precisa ser:wc -L <left.txt
... porque, quando um nome de arquivo é especificado como uma linha de comando arg , seu nome é enviado para stdoutIsso é de várias etapas, portanto não é ideal, mas aqui vai.
1) Encontre o comprimento da linha mais longa em
file1.txt
.Com o seu exemplo, a linha mais longa é 22.
2) Use awk para preencher
file1.txt
, preenchendo cada linha com menos de 22 caracteres até 22 com aprintf
instruçãoNota: Para o FS, use uma sequência que não exista
file1.txt
.3) Use a pasta como você fez antes.
Se isso é algo que você faz com frequência, isso pode ser facilmente transformado em um script.
fonte
while IFS= read -r line
; caso contrário, o shell irá alterar os espaços em branco e as barras invertidas. Mas o shell não é a melhor ferramenta para esse trabalho; versões recentes do coreutils GNU terwc -L
(ver resposta de Fred), ou você pode usar awk:awk 'n<length {n=length} END {print +n}'
.Não consigo comentar a resposta de glenn jackman, por isso estou adicionando isso para resolver o problema de células vazias que Peter.O observou. A adição de um caractere nulo antes de cada guia elimina as execuções de delimitadores que são tratados como uma única quebra e solucionam o problema. (Eu originalmente usei espaços, mas usar o caractere nulo elimina o espaço extra entre as colunas.)
Se o caractere nulo causar problemas por vários motivos, tente:
ou
Ambas
sed
ecolumn
parecem variar na implementação entre os tipos e versões do Unix / Linux, especialmente BSD (e Mac OS X) vs. GNU / Linux.fonte
od -c
e não vejo bytes nulos. Isso é no centos e no ubuntu.\0
não funcionou como umnull
no sed, mas\x0
funcionou. No entanto, a coluna deu umline too long
erro. A coisa mais simples parece ser usar um espaço e conviver com o personagem extra.Com base na resposta de bahamat : isso pode ser feito inteiramente
awk
, lendo os arquivos apenas uma vez e não criando nenhum arquivo temporário. Para resolver o problema como indicado, façaComo em muitos
awk
scripts desse tipo, o acima é lido primeirofile1
, salvando todos os dados dasave
matriz e computando simultaneamente o comprimento máximo da linha. Em seguida, ele lêfile2
e imprime osfile1
dados salvos ( ) lado a lado com osfile2
dados atuais ( ). Por fim, sefile1
for maior quefile2
(tem mais linhas), imprimimos as últimas linhas defile1
(aquelas para as quais não há linha correspondente na segunda coluna).Em relação ao
printf
formato:"%-nns"
imprime uma string justificada à esquerda em um campo denn
caracteres."%-*s", nn
faz a mesma coisa - o*
diz para tirar a largura do campo do próximo parâmetro.maxlength+2
nn
+2
O script acima funciona apenas para dois arquivos. Ele pode ser modificado trivialmente para manipular três arquivos ou para quatro arquivos etc., mas isso seria tedioso e é deixado como um exercício. No entanto, não é difícil modificá-lo para lidar com qualquer número de arquivos:
Isso é muito semelhante ao meu primeiro script, exceto
max_length
em uma matriz.max_FNR
em uma matriz.save
em uma matriz bidimensional.END
bloco.fonte
paste
é a melhor solução; especificamente, de Glenn Jackmanpaste file1 file2 | column -s $'\t' -t
. Mas pensei que seria divertido tentar melhorar aawk
abordagem.