Eu tenho um arquivo chamado Element_query
contendo o resultado de uma consulta:
SQL> select count (*) from element;
[Output of the query which I want to keep in my file]
SQL> spool off;
Eu quero excluir a primeira linha e a última linha usando o comando shell.
Respostas:
Usando o GNU
sed
:Como funciona :
-i
opção editar o próprio arquivo. Você também pode remover essa opção e redirecionar a saída para um novo arquivo ou outro comando, se desejar.1d
exclui a primeira linha (1
para agir apenas na primeira linha,d
para excluí-la)$d
exclui a última linha ($
para atuar apenas na última linha,d
para excluí-la)Indo além :
1,5d
excluiria as 5 primeiras linhas.SQL>
uso da instrução/^SQL> /d
/^$/d
statement1;statement2;satement3;...
) ou especificando-as separadamente na linha de comando (-e 'statement1' -e 'statement 2' ...
)fonte
1,3d
excluirá as três primeiras linhas), mas é um pouco mais difícil para o final. Dependendo do que você deseja, é melhor usar isso:sed -i '/^SQL> /d' Element_query
para excluir as linhas que começamSQL>
sem importar onde estão no arquivo.sed
one-liner - que funcionará para remover contagens arbitrárias de linhas do cabeçalho e do final de um arquivo. Melhor ainda, desde que a entrada seja um arquivo regular, seja apenas para agrupar uma única entrada em doishead
processos - é o maneira mais rápida de fazer isso normalmente.sed -i '1d' table-backup.sql
excluir a primeira linha do arquivo de texto sqlcabeça; cabeça
Com o exposto, você pode especificar o primeiro número de linhas a serem removidas da cabeça da saída com o primeiro
head
comando e o número de linhas a serem gravadasoutfile
com o segundo. Ele também costuma fazer isso mais rápido do quesed
- especialmente quando a entrada é grande - apesar de exigir duas invocações. Ondesed
definitivamente deve ser preferido, porém, é no caso em que<infile
é não um regular, lseekable arquivo - porque isso irá normalmente não funcionar como o esperado nesse caso, massed
pode lidar com todas as modificações de saída em um único processo, roteirizado.Com um GNU,
head
você também pode usar a-
forma negativa[num]
no segundo comando. Nesse caso, o seguinte comando removerá a primeira e a última linha da entrada:OU com um POSIX
sed
:Digamos, por exemplo, eu estava lendo uma entrada de 20 linhas e queria retirar as 3 e as 7 primeiras. Se resolvesse fazer isso com /
sed
, faria com um buffer de cauda. Eu adicionaria primeiro três e sete para uma contagem total de dez e depois faria:Esse é um exemplo que retira as 3 primeiras e as 7 últimas linhas da entrada. A idéia é que você pode armazenar em buffer quantas linhas desejar retirar da cauda da entrada no espaço do padrão em uma pilha, mas apenas
P
criar a primeira delas para cada linha puxada.1,10
sed
P
não há nada porque, para cada uma delas, está empilhando a entrada no espaço do padrão linha por linha em umb
loop de rancho.sed
a pilha éd
eliminada - e, assim, as três primeiras linhas são retiradas da saída de uma só vez.sed
atinge a$
última linha de entrada e tenta puxar oN
ext, atinge o EOF e para o processamento completamente. Mas naquele tempo, o espaço do padrão contém todas as linhas14,20
- nenhuma das quais ainda foiP
criada e nunca é.sed
P
apenas as linhas de ew ocorrem\n
no espaço do padrão e asD
exclui antes de iniciar um novo ciclo com o que resta - ou as próximas 6 linhas de entrada. A sétima linha é anexada novamente à pilha com oN
comando ext no novo ciclo.E assim, da
seq
saída de (que é 20 linhas numeradas seqüencialmente) ,sed
apenas imprime:Isso se torna problemático quando o número de linhas que você deseja extrair da cauda da entrada é grande - porque
sed
o desempenho é diretamente proporcional ao tamanho do espaço do padrão. Ainda assim, porém, é uma solução viável em muitos casos - e o POSIX especifica umsed
espaço padrão para lidar com pelo menos 4kb antes de ser eliminado.fonte
tail
também suporta atail -n+<num>
sintaxe estendida, que significa "iniciar da linha<num>
"Não vou responder como excluir várias linhas. Vou atacar o problema desta maneira:
grep -v '#SQL>' Element_query >outfile
Em vez de contar linhas, elimina os comandos SQL reconhecendo os prompts. Essa solução pode ser generalizada para outros arquivos de saída de sessões SQL com mais comandos do que apenas dois.
fonte
ed
é 'o editor de texto padrão' e deve estar disponível em sistemas que não possuem GNUsed
. Foi originalmente projetado como um editor de texto, mas é adequado para scripts.1d
exclui a primeira linha do arquivo$d
(citada para que o shell não pense que seja uma variável) exclui a última linha,w
grava o arquivo eq
saied
.printf
aqui é usado para formatar os comandos paraed
- cada um deve ser seguido por uma nova linha; é claro que existem outras maneiras de conseguir isso.fonte
Existem várias maneiras de remover as linhas inicial e final de um arquivo.
Você pode usá-
awk
lo, pois lida com a correspondência de padrões e a contagem de linhas,Você pode usar
grep -v
para excluir linhas que não deseja por padrão e pode combinar vários padrões usando a-E
opçãoVocê pode usar
head
etail
aparar contagens específicas de linhas,Você pode usar
vi/vim
e excluir a primeira e a última linha (s),você pode usar um script perl, pular a primeira linha, salvar cada linha, imprimir quando chegar a próxima linha,
fonte
head
s, você realmente não precisa do cachimbo e, de fato, é melhor não usá-lo, se você puder se safar. Quando você faz issohead | head
- enquanto os dois processos podem ser executados simultaneamente, eles também estão processando praticamente todos os mesmos dados de forma redundante. Se você fizer{ head >dump; head >save; } <in
isso, pule apenas por deslocamento - o primeiro lê 10 linhas>dump
e o segundo lê as próximas 10 linhas>save
.Você seria muito melhor servido cortando os comandos SQL. Você pode fazer isso de duas maneiras:
Se você tiver certeza absoluta de que a sequência "
SQL>
" não ocorre em nenhum outro lugar na saída,Se você não tem tanta certeza,
A segunda versão é mais lenta, porém mais precisa: ela ignora as linhas que começam exatamente com "SQL>" e terminam em ponto e vírgula, que parecem descrever as linhas que você deseja eliminar.
No entanto, seria melhor não colocar essa saída extra no arquivo para começar. A maioria dos sistemas SQL tem alguma maneira de fazer isso. Não estou muito familiarizado com a Oracle, mas talvez essa resposta possa ser útil.
fonte
Você pode selecionar as linhas entre um intervalo
awk
(isso pressupõe que você saiba quantas linhas existem):Ou no Perl:
Se você não souber quantas linhas existem, poderá calculá-lo em tempo real usando
grep
(observe que isso não contará linhas em branco, usegrep -c '' file
-as também):fonte
Experimente esta solução:
Costumização
Você pode adaptá-lo facilmente para excluir as n primeiras linhas alterando o
+2
detail
;ou para excluir as últimas n linhas, alterando o
-1
dehead
.fonte
Usando
awk
:< inputfile
: Redireciona o conteúdoinputfile
deawk
'sstdin
> outputfile
: redireciona o conteúdo deawk
'sstdout
paraoutputfile
NR>1
: executa as seguintes ações apenas se o número do registro que está sendo processado for maior que 1{print r}
: imprime o conteúdo da variávelr
{r=$0}
: atribui o conteúdo do registro que está sendo processado à variávelr
Portanto, na primeira execução do
awk
script, o primeiro bloco de ações não é executado, enquanto o segundo bloco de ações é executado e o conteúdo do registro é atribuído à variávelr
; na segunda execução, o primeiro bloco de ações é executado e o conteúdo da variávelr
é impresso (para que o registro anterior seja impresso); isso tem o efeito de imprimir cada linha processada, mas a primeira e a última.fonte
r
.