한 줄씩 추출한 다음 별도의 파일에 저장

한 줄씩 추출한 다음 별도의 파일에 저장

나는 행운을 시험해 보았지만 grep어쩐지 sed제대로 된 결과를 얻을 수 없었습니다.

크기가 약 8GB인 로그 파일이 있습니다. 15분 동안 의심스러운 활동을 분석해야 합니다. 로그 파일에서 확인해야 할 부분을 찾았고 해당 줄을 추출하여 별도의 파일에 저장하려고 합니다. 일반 CentOS 시스템에서는 어떻게 할 수 있나요?

나의 마지막 시도는 이것이었지만 작동하지 않았습니다. 나는 sed그러한 유형의 명령 에 관해서는 당황합니다 .

sed -n '2762818,2853648w /var/log/output.txt' /var/log/logfile

답변1

sed -n '2762818,2853648p' /var/log/logfile > /var/log/output.txt

p인쇄용입니다

답변2

아마도 이를 수행하는 가장 좋은 방법은 다른 사람들이 언급한 것처럼 쉘 리디렉션을 사용하는 것입니다. sed그러나 개인적으로 선호하는 방법은 아마도 head파일에서 너무 많은 줄만 가져오도록 설계된 것보다 이 작업을 더 효율적으로 수행하지는 않을 것입니다.

head -n[num] | tail -n[num]이 사이트에는 대용량 파일의 경우 매번 성능이 뛰어남을 입증하는 다른 답변이 있지만 sed파이프를 완전히 피하는 것보다 더 빠를 수도 있습니다.

다음과 같은 파일을 만들었습니다.

echo | dd cbs=5000000 conv=block | tr \  \\n >/tmp/5mil_lines

그리고 나는 그것을 실행했습니다 :

{ head -n "$((ignore=2762817))" >&2
  head -n "$((2853648-ignore))" 
} </tmp/5mil_lines 2>/dev/null  |
sed -n '1p;$p'                

나는 sed당신에게 보여주기 위해 첫 번째 줄과 마지막 줄만 잡기 위해 전혀 사용하지 않았습니다 ...

2762818
2853648

이는 명령을 그룹화하고 { ... ; }그룹에 대한 입력을 리디렉션할 때 ... ; } <input모든 명령이 동일한 입력을 공유하기 때문에 작동합니다. 대부분의 명령은 infile을 읽는 동안 전체 infile을 소진하므로 일반적으로 infile의 머리부터 꼬리까지 읽고 아무것도 남지 않는 { cmd1 ; cmd2; } <infile경우가 있습니다.cmd1cmd2

head그러나 는 지시받은 대로 항상 해당 파일을 통해 탐색합니다.

{ head -n [num] >/dev/null
  head -n [num]
} <infile 

[num]...첫 번째는 출력을 탐색 하고 덤프 /dev/null하고 두 번째는 첫 번째가 떠난 곳에서 읽기를 시작하도록 남겨진 경우입니다.

넌 할 수있어...

{ head -n "$((ignore=2762817))" >/dev/null
  head -n "$((2853648-ignore))" >/path/to/outfile
} <infile

이 구성은 다른 종류의 복합 명령에서도 작동합니다. 예를 들어:

set "$((n=2762817))" "$((2853648-n))"
for n do head "-n$n" >&"$#"; shift
done <5mil_lines 2>/dev/null | 
sed -n '1p;$p'

...인쇄...

2762818
2853648

하지만 다음과 같이 작동할 수도 있습니다.

d=$(((  n=$(wc -l </tmp/5mil_lines))/43 ))      &&
until   [ "$(((n-=d)>=(!(s=143-n/d))))" -eq 0 ] &&
        head "-n$d" >>"/tmp/${s#1}.split"
do      head "-n$d" > "/tmp/${s#1}.split"       || ! break
done    </tmp/5mil_lines

쉘 위에서 처음에는 $n$d변수를 다음으로 설정합니다.

  • $n
    • wc내 테스트 파일에 대해 보고된 줄 수/tmp/5mil_lines
  • $d
    • 여기서 43 의 몫은 $n/43임의로 선택된 제수입니다.

그런 다음 less 값으로 감소한 until것을 반복합니다 . 그렇게 하는 동안 분할 횟수를 에 저장 하고 루프에서 해당 값을 사용 하여 . 결과적으로 각 반복마다 infile에 있는 동일한 수의 ewline으로 구분된 필드를 새로운 outfile로 읽어 들여 루프가 진행되는 동안 동일하게 43번 분할합니다. 인파일을 2번 이상 읽지 않고도 이를 관리합니다. 처음에는 라인 수를 계산하는 시기이고, 나머지 작업에서는 매번 아웃파일에 쓰는 만큼의 라인만 읽습니다.$n$d$d$s>/tmp/[num].split\nwc

실행한 후 결과를 확인해 보니 다음과 같습니다.

tail -n1 /tmp/*split | grep .

산출:

==> /tmp/01.split <==
116279  
==> /tmp/02.split <==
232558  
==> /tmp/03.split <==
348837  
==> /tmp/04.split <==
465116  
==> /tmp/05.split <==
581395  
==> /tmp/06.split <==
697674  
==> /tmp/07.split <==
813953  
==> /tmp/08.split <==
930232  
==> /tmp/09.split <==
1046511 
==> /tmp/10.split <==
1162790 
==> /tmp/11.split <==
1279069 
==> /tmp/12.split <==
1395348 
==> /tmp/13.split <==
1511627 
==> /tmp/14.split <==
1627906 
==> /tmp/15.split <==
1744185 
==> /tmp/16.split <==
1860464 
==> /tmp/17.split <==
1976743 
==> /tmp/18.split <==
2093022 
==> /tmp/19.split <==
2209301 
==> /tmp/20.split <==
2325580 
==> /tmp/21.split <==
2441859 
==> /tmp/22.split <==
2558138 
==> /tmp/23.split <==
2674417 
==> /tmp/24.split <==
2790696 
==> /tmp/25.split <==
2906975 
==> /tmp/26.split <==
3023254 
==> /tmp/27.split <==
3139533 
==> /tmp/28.split <==
3255812 
==> /tmp/29.split <==
3372091 
==> /tmp/30.split <==
3488370 
==> /tmp/31.split <==
3604649 
==> /tmp/32.split <==
3720928 
==> /tmp/33.split <==
3837207 
==> /tmp/34.split <==
3953486 
==> /tmp/35.split <==
4069765 
==> /tmp/36.split <==
4186044 
==> /tmp/37.split <==
4302323 
==> /tmp/38.split <==
4418602 
==> /tmp/39.split <==
4534881 
==> /tmp/40.split <==
4651160 
==> /tmp/41.split <==
4767439 
==> /tmp/42.split <==
4883718 
==> /tmp/43.split <==
5000000 

답변3

아래와 같은 명령 조합을 head사용 하여 이 작업을 수행할 수 있습니다 .tail

head -n{to_line_number} logfile | tail -n+{from_line_number} > newfile

from_line_number및를 to_line_number원하는 줄 번호로 바꾸세요 .

테스트

cat logfile
This is first line.
second
Third
fourth
fifth
sixth
seventh
eighth
ninth
tenth

##I use the command as below. I extract from 4th line to 10th line. 

head -n10 logfile | tail -n+4 > newfile
fourth
fifth
sixth
seventh
eighth
ninth
tenth

관련 정보