Gostaria de reverter a ordem das linhas em um arquivo de texto (ou stdin), preservando o conteúdo de cada linha.
Então, ou seja, começando com:
foo
bar
baz
Eu gostaria de terminar com
baz
bar
foo
Existe um utilitário de linha de comando UNIX padrão para isso?
shell
unix
command-line
Scotty Allen
fonte
fonte
perl -e 'print reverse <>'
mas provavelmente também se aplica a outros métodos).Respostas:
Cauda BSD:
Referência: FreeBSD páginas de manual do , NetBSD , OpenBSD e OS X.
fonte
Também vale a pena mencionar:
tac
(o, ahem, reverso decat
). Parte dos coreutils .Virando um arquivo para outro
fonte
brew install coreutils
(instala comogtac
padrão).echo -n "abc\ndee" > test; tac test
.Existem os conhecidos truques sed :
(Explicação: acrescente uma linha não inicial para reter o buffer, troque a linha e retenha o buffer, imprima a linha no final)
Como alternativa (com execução mais rápida) dos awk one-liners :
Se você não se lembra disso,
Em um sistema com utilitários GNU, as outras respostas são mais simples, mas nem todo mundo é GNU / Linux ...
fonte
tail -r
e tac.tac
espera-se que lide com arquivos grandes arbitrários que não cabem na memória (o comprimento da linha ainda é limitado). Não está claro se ased
solução funciona para esses arquivos.no final do seu comando, coloque:
| tac
O tac faz exatamente o que você está pedindo: "Escreva cada arquivo na saída padrão, a última linha primeiro."
tac é o oposto de cat :-).
fonte
tac
comando, isso é útil para novos usuários que podem acabar pesquisando o mesmo assunto.Se você estiver em
vim
usofonte
exemplo:
fonte
Tente
tac
, que funciona no Linux, e se isso não funcionartail -r
, use , que funciona no BSD e OSX.fonte
tac myfile.txt
- o que estou perdendo?tail -r
casotac
não estiver disponível.tac
não é compatível com POSIX. Nem étail -r
. Ainda não é infalível, mas isso aumenta as chances de as coisas funcionarem.tac
estiver disponível, mas ficar sem RAM e trocar no meio do consumo de um fluxo de entrada gigante. Ele falha e, em seguida,tail -r
consegue processar o restante do fluxo, fornecendo um resultado incorreto.brew install coreutils
e usogtac
no lugar dotac
e se o seu preferem add tac como um alias paragtac
se por exemplo você queria um shell script que usou várias plataformas (Linux, OSX)Tente o seguinte comando:
fonte
sed 's/^[0-9]*://g'
nl
por padrão, não conseguirá numerar as linhas vazias. A-ba
opção está disponível em alguns sistemas, não é universal (o HP / UX vem à mente, mas eu gostaria que não fosse), enquantogrep -n
sempre numerará todas as linhas que correspondem ao regex (neste caso vazio).cut -d: -f2-
Just Bash :) (4.0 ou superior)
fonte
-nenenenenenene
e testemunhe o motivo pelo qual as pessoas recomendam sempre o uso emprintf '%s\n'
vez deecho
.O método mais simples é usar o
tac
comandotac
écat
inverso. Exemplo:fonte
Eu realmente gosto da resposta " tail -r ", mas minha resposta favorita é ...
fonte
mawk
Ubuntu 14.04 LTS - funciona, por isso não é específico ao GNU awk. 1n++
pode ser substituído porNR
EDITAR o seguinte gera uma lista aleatória de números de 1 a 10:
onde os pontos são substituídos pelo comando real que inverte a lista
tac
python: usando [:: - 1] no sys.stdin
fonte
Para uma solução OS cruzada (OSX, Linux) que pode usar
tac
dentro de um script de shell, use homebrew como os outros mencionaram acima;Instalar lib
Para MacOS
Para linux debian
Em seguida, adicione o alias
fonte
Isso funcionará no BSD e no GNU.
fonte
Se você deseja modificar o arquivo no local, pode executar
Isso elimina a necessidade de criar um arquivo temporário e excluir ou renomear o original e tem o mesmo resultado. Por exemplo:
Baseado na resposta de ephemient , que fez quase, mas não exatamente, o que eu queria.
fonte
Acontece que eu quero obter as últimas
n
linhas de um arquivo de texto muito grande com eficiência .A primeira coisa que tentei é
tail -n 10000000 file.txt > ans.txt
, mas achei muito lento, poistail
tem que procurar o local e depois voltar para imprimir os resultados.Quando eu perceber, eu mudar para outra solução:
tac file.txt | head -n 10000000 > ans.txt
. Desta vez, a posição de busca só precisa se mover do final para o local desejado e economiza 50% de tempo !Leve para casa a mensagem:
Use
tac file.txt | head -n n
se o seutail
não tiver a-r
opção.fonte
Melhor solução:
fonte
Para usuários do Emacs:
C-x h
(selecione o arquivo inteiro) e depoisM-x reverse-region
. Também funciona apenas para selecionar partes ou linhas e revertê-las.fonte
Eu vejo muitas idéias interessantes. Mas tente minha ideia. Canalize seu texto para isso:
que assume que o caractere '~' não está no arquivo. Isso deve funcionar em todos os shell UNIX desde 1961. Ou algo assim.
fonte
Eu tinha a mesma pergunta, mas também queria que a primeira linha (cabeçalho) permanecesse no topo. Então eu precisava usar o poder do awk
PS também funciona em cygwin ou gitbash
fonte
1\n20\n19...2\n
vez de20\n19...\2\n1\n
.Você pode fazer isso com
vim
stdin
estdout
. Você também pode usarex
para ser compatível com POSIX .vim
é apenas o modo visual paraex
. De fato, você pode usarex
comvim -e
ouvim -E
(ex
modo aprimorado ).vim
é útil porque, ao contrário de ferramentas comosed
essa, armazena em buffer o arquivo para edição, enquantosed
é usado para fluxos. Você pode usarawk
, mas terá que armazenar manualmente manualmente tudo em uma variável.A ideia é fazer o seguinte:
g/^/m0
. Isso significa globalmente, para cada linhag
; coincidir com o início da linha, que corresponde a qualquer coisa^
; mova-o após o endereço 0, que é a linha 1m0
.%p
. Isso significa para o intervalo de todas as linhas%
; imprima a linhap
.q!
. Isso significa sairq
; com força!
.Como tornar isso reutilizável
Eu uso um script que chamo
ved
(como o editor vimsed
) para usar o vim para editarstdin
. Adicione isso a um arquivo chamadoved
no seu caminho:Estou usando um
+
comando em vez de+'%p' +'q!'
, porque o vim limita você a 10 comandos. Então, mesclá-los permite"$@"
que você tenha 9+
comandos em vez de 8.Então você pode fazer:
Se você não possui o vim 8, insira isso
ved
:fonte
ou
ou
fonte
tail -r funciona na maioria dos sistemas Linux e MacOS
seq 1 20 | cauda -r
fonte
ou
fonte
sort -r
só funciona se a entrada já estiver classificada, o que não é o caso aqui.rev
inverte os caracteres por linha, mas mantém a ordem das linhas intacta, o que também não é o que Scotty pediu. Portanto, esta resposta é realmente nenhuma resposta.