Quero imprimir as linhas de números ímpares e pares de arquivos.
Eu encontrei este script de shell que faz uso de eco.
#!/bin/bash
# Write a shell script that, given a file name as the argument will write
# the even numbered line to a file with name evenfile and odd numbered lines
# in a text file called oddfile.
# -------------------------------------------------------------------------
# Copyright (c) 2001 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
file=$1
counter=0
eout="evenfile.$$" # even file name
oout="oddfile.$$" # odd file name
if [ $# -eq 0 ]
then
echo "$(basename $0) file"
exit 1
fi
if [ ! -f $file ]
then
echo "$file not a file"
exit 2
fi
while read line
do
# find out odd or even line number
isEvenNo=$( expr $counter % 2 )
if [ $isEvenNo -ne 0 ]
then
# even match
echo $line >> $eout
else
# odd match
echo $line >> $oout
fi
# increase counter by 1
(( counter ++ ))
done < $file
echo "Even file - $eout"
echo "Odd file - $oout"
Mas não há uma maneira de fazer isso em uma linha?
Sim, use awk, eu li.
Linhas numeradas pares:
awk 'NR % 2' filename
linhas ímpares:
awk 'NR % 2 == 1' filename
Mas isso não funciona para mim. Ambos produzem a mesma saída, de acordo com o diff. Quando comparados com o arquivo original, os dois têm metade do comprimento e as linhas com números ímpares. Estou fazendo algo errado?
text-processing
sed
awk
ixtmixilix
fonte
fonte
NR % 2 == 0
, caso contrário, é equivalente ao segundo.Respostas:
Como você perguntou "em uma linha":
Observe que a maior parte do código é devido à sua escolha de nome de arquivo de saída sofisticado. Caso contrário, o código a seguir seria suficiente para colocar linhas ímpares na “linha 1” e linhas pares na “linha 0”:
fonte
Eu prefiro ser compatível com POSIX, sempre que possível, então pensei em publicar este método alternativo. Costumo usá-los para alterar o texto antes dos
xargs
pipelines.Imprimir linhas pares numeradas,
Imprimir linhas numeradas ímpares,
Embora eu costumo usar
awk
, é um exagero para esse tipo de tarefa.fonte
Isso é fácil:
imprimirá linhas pares do nome do arquivo
imprimirá linhas com números ímpares.
fonte
awk
, pessoalmente eu o uso com muita frequência. Eu nunca disse que algo não era 'POSIX'awk
, estava me referindo àssed
opções da resposta . Especificamente, o~
operador é uma extensão GNU, que ainda é aceitável para muitas pessoas. Em relação a 'usar o AWK, I personally believe using
externamente awk' para esta tarefa simples, é um exagero. Portanto, o +1 era para concluir a tarefased
, um utilitário mais leve que oawk
.Para números pares, o código deve ser
& para números ímpares
fonte
gawk 'FS=",";NF%2==0' file.csv
.Você pode fazer isso com uma única
sed
chamada, sem necessidade de ler o arquivo duas vezes:ou, se preferir em uma linha:
Observe que eles não fornecerão o resultado esperado se um arquivo contiver apenas uma linha (a linha será
w
copiada emeven
vez deodd
a primeiran
não ser executada). Para evitar isso, adicione uma condição:Como funciona ? Bem, ele usa três
sed
comandos:n
- se não estiver na última linha, imprima o espaço do padrão parastdout
(que é redirecionado para o arquivoodd
), substitua-o pela próxima linha (agora está processando uma linha par) e continue executando os comandos restantesw
- acrescente o espaço do padrão a ser arquivadoeven
d
- exclua o espaço do padrão atual e reinicie o ciclo - o efeito colateral disso é quesed
nunca imprimirá automaticamente o espaço do padrão, pois nunca alcançará o final do scriptEm outras palavras,
n
é executado apenas em linhas ímpares ew
ed
são executados apenas em linhas pares.sed
nunca chega à impressão automática, a menos que, como eu disse, a entrada consista em uma única linha.fonte
Tente o seguinte:
fonte
Eu iria
perl
porque gosto deperl
:Usa o fato de que
-p
implicitamente imprime, para replicar comosed
funciona - e usamosselect
para escolher qual identificador de arquivo no qual ele grava.fonte