나는 행운을 시험해 보았지만 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
모든 명령이 동일한 입력을 공유하기 때문에 작동합니다 . 대부분의 명령은 읽을 때 전체 내부 파일을 소모하므로 어떤 경우에는 내부 파일의 헤드부터 테일까지 읽고 아무것도 남기지 않는 { cmd1 ; cmd2; } <infile
것이 일반적입니다 .cmd1
cmd2
head
그러나 항상 지시된 대로 해당 infile을 통해서만 검색하므로...
{ 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
임의로 선택된 제수입니다.
- 여기서 43의 몫은
그런 다음 루프는 until
이를 더 작은 값 $n
으로 감소시킵니다 . 이렇게 하면 분할 횟수를 저장 하고 루프에서 해당 값을 사용하여 이름이 지정된 출력 파일을 증가시킵니다 . 결과적으로 각 반복은 infile에서 새 outfile로 동일한 수의 ewline으로 구분된 필드를 읽어 루프 동안 평균 43번 분할합니다. infile을 2번 이상 읽지 않고 이를 관리합니다. 첫 번째는 행 수를 계산할 때이고, 나머지 작업에서는 매번 outfile에 쓰는 만큼의 행만 읽습니다.$d
$d
$s
>
/tmp/[num].split
\n
wc
실행 후 다음과 같은 결과를 확인했습니다.
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