홀수 라인 인쇄, 짝수 라인 인쇄


18

홀수 번호와 짝수 번호 줄을 파일에서 인쇄하고 싶습니다.

echo를 사용하는이 쉘 스크립트를 찾았습니다.

#!/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"

그러나 한 줄로 할 수있는 방법이 없습니까?

예, awk를 사용하십시오 .

짝수 라인 :

awk 'NR % 2' filename

홀수 라인 :

awk 'NR % 2 == 1' filename

그러나 그것은 나를 위해 작동하지 않습니다. diff에 따르면 둘 다 동일한 출력을 생성합니다. 원본 파일과 비교할 때 파일의 길이는 실제로 절반이며 홀수 줄이 들어 있습니다. 내가 뭔가 잘못하고 있습니까?


6
첫 번째는이어야하며 NR % 2 == 0, 그렇지 않으면 두 번째 것과 같습니다.
enzotib

NR % 2가 짝수 줄을 제공한다는 내용의 검색 맨 위에 표시되는 여러 문서 (이 문서를 포함하여)가 온라인에있는 것 같습니다. 정확하지 않습니다 .1 % 2 = 1이기 때문에 홀수를 제공합니다 = 참, 2 % 2 = 0 = 거짓.
deltaray 2012 년

답변:


12

“한 줄에”물었을 때 :

awk '{print>sprintf("%sfile.%d",NR%2?"odd":"even",PROCINFO["pid"])}' filename

대부분의 코드는 멋진 출력 파일 이름 선택으로 인한 것입니다. 그렇지 않으면 다음 코드는 "line-1"에 홀수 라인을, "line-0"에 라인을 배치하기에 충분합니다.

awk '{print>"line-"NR%2}' filename

26

가능하면 POSIX 호환을 선호하므로이 대안 방법을 게시 할 것이라고 생각했습니다. 나는 종종 xargs파이프 라인 전에 텍스트를 엉망으로 만드는 데 사용합니다 .

짝수 줄 인쇄,

sed -n 'n;p'

홀수 줄 인쇄,

sed -n 'p;n'

종종을 사용하지만 awk이 유형의 작업에는 과잉입니다.


14

쉽습니다.

 sed -n 2~2p filename

파일 이름에서 짝수 줄을 인쇄합니다

sed -n 1~2p filename

홀수 라인을 인쇄합니다.


1
외부 적으로 AWK를 사용하지 않는 경우 +1 POSIX sed는 아니지만 여전히 견고한 방법입니다.
JM Becker

@TechZilla "외부 적으로 AWK 사용"을 이해하지 못합니다. awk도 POSIX입니다.
jw013

3
@ jw013 :에 아무런 문제가 없습니다 awk. 개인적으로 매우 자주 사용합니다. 나는 'POSIX 아님'에 대해 아무것도 말하지 않았 awk으며 대답의 sed옵션을 언급하고있었습니다 . 특히 ~연산자는 GNU 확장이며 많은 사람들이 여전히 사용할 수 있습니다. , I personally believe using 이 간단한 작업 에 '외부 적으로 AWK를 사용하는 것'에 관해서 는 과잉입니다. 따라서 +1은 sed보다 가벼운 유틸리티로 작업을 완료하기위한 것 awk입니다.
JM Becker

1
누군가 ~ 연산자가 어떻게 작동하는지 설명해 주시겠습니까?
Forever Learner

9

짝수의 경우 코드는

awk 'NR%2==0' filename

& 홀수

awk 'NR%2==1' filename

1
이건 완벽 해 10 단위로 행을 가져와야하는 경우에도 작동합니다. 예를 들어 100 만 크기로 정렬 된 파일 크기를 줄여야합니다. 이것이 바로 내가 원하는 것입니다.
Dexter

짝수 열을 AWK로 어떻게 인쇄 할 수 있습니까? 나는 이것을 작동시킬 수 없다 gawk 'FS=",";NF%2==0' file.csv.
hhh

2

한 번의 sed호출로 파일을 두 번 읽을 필요없이 수행 할 수 있습니다 .

sed '$!n
w even
d' infile > odd

또는 한 줄을 선호하는 경우 :

sed -e '$!n' -e 'w even' -e d infile > odd

파일에 한 줄만 포함 된 경우 예상 한 결과를 w얻지 못합니다 ( 첫 번째 줄 이 실행되지 even않고 줄이 리 텐트 됨 ). 이를 피하려면 조건을 추가하십시오.oddn

sed -e '$!n' -e '1!{w even' -e 'd}' infile > odd

어떻게 작동합니까? 글쎄, 그것은 세 가지 sed명령을 사용 합니다 :
n-마지막 줄에 없으면 패턴 공간을 (파일로 리디렉션 됨 ) 인쇄 하고 다음 줄로 바꿉니다 (따라서 짝수 줄을 처리합니다). 그리고 나머지 명령을 계속 실행하십시오 -추가 파일로 저장할 패턴 공간 -현재 패턴 공간을 삭제하고주기를 다시 시작합니다. 이것의 부작용 은 패턴 공간이 스크립트의 끝에 도달하지 않기 때문에 자동으로 인쇄되지 않습니다.stdoutodd
weven
dsed

즉, n홀수 라인에서 실행되고, wd짝수 라인이 실행된다. sed내가 말했듯이 입력이 한 줄로 구성되어 있지 않으면 자동 인쇄에 도달하지 않습니다.


어떻게 작동하는지 자세히 설명해 주시겠습니까?
Forever Learner

도와 주셔서 감사합니다. 진심으로 감사드립니다.
Forever Learner

0

이 시도:

awk '{if(NR%2){print $0 > "odd.file"}else{print $0 > "even.file"}}' filename

레코드 번호를 출력 하시겠습니까?
manatwork

그것에 대해 유감스럽게도 전체 줄을 출력하도록 수정했습니다.
renma

0

내가 perl좋아하기 때문에 함께 갈 것입니다 perl:

perl -pe 'BEGIN{open($e,">even_lines");open($o,">odd_lines")} $. % 2 ?select $o:select $e;'

-p암시 적으로 인쇄 한다는 사실을 사용하여 sed작동 방식 을 복제 하고 우리는 select어떤 파일 핸들을 쓸 것인지 선택합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.