Bash : 파일에서 몇 줄을 가져 와서 다른 파일에 출력을 저장하는 방법 [닫힌]
이와 같은 로그 파일이 있습니다.
$ cat build.log
..........
[ 60% 60917/101076] AAPT2 compile ....
[ 60% 60918/101076] AAPT2 compile ....
[ 60% 60919/101076] AAPT2 compile ....
[ 60% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
#### failed to build some targets (17:26 (mm:ss)) ####
새 파일 로그의 출력이 다음과 같도록 구문 분석 된 새 로그처럼 생성하는 방법 :
$ cat parsed.log
[ 60% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
#### failed to build some targets (17:26 (mm:ss)) ####
[ 60% 60920/101076]
grep, sed 등을 사용하여 파일이 끝날 때까지 마지막 진행 상황 만 가져옵니다 . 감사합니다
답변
다음은 펄입니다.
$ perl -0777 -lne 'print $1 if /(^\[[^[]*\z)/m' file
또는 펄 파이프 :
$ perl -E 'say reverse <>' file | perl -lpE 'if (/^\[/){ say; last}' | perl -E 'say reverse <>'
를 들어 awk
당신은 할 수 있습니다 :
$ awk 'BEGIN{RS="\\["}END{print "[" $0}' file
물론 실패가 항상 3 줄이면 가장 간단한 방법은 다음을 사용하는 것입니다 tail
.
$ tail -n 3 file
모든 인쇄 :
[ 60% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
$ cat build.log ........ [ 60% 60917/101076] AAPT2 compile .... [ 60% 60918/101076] AAPT2 compile .... [ 60% 60919/101076] AAPT2 compile .... [ 60% 60920/101076] AAPT2 compile .... ninja: build stopped: subcommand failed. 21:41:22 ninja failed with: exit status 1 $ awk '$2 != n[2]{print p} {p = $0; split(p,n,FS)} END{print p}' build.log
........
[ 60% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
awk
이런 종류의 작업에 적합한 도구입니다. 여기에서 두 번째 필드가 이전 줄의 두 번째 필드와 일치하는지 확인하고 일치하면 인쇄합니다. 그런 다음 이전 줄을 저장하고 반복하십시오. 항상 입력의 마지막 줄을 인쇄하십시오.
이것은 당신을 위해 일할 것입니다 (GNU sed) :
sed '/^\[/h;//!H;$!d;x' file
행이 시작 [
되면 보류 공간에 저장합니다 (이전에 있던 항목을 덮어 씁니다).
그렇지 않으면 현재 행을 보류 공간에 추가하십시오.
마지막 줄을 제외한 모든 줄을 삭제합니다.
파일 끝에서 보류 공간으로 바꾸고 내용을 인쇄합니다.
줄 순서를 변경하지 않고 이러한 종류의 필터를 수행하려는 경우 때때로 운이 좋지 않습니다. 그리고 그 라인이 파일의 시작에 서면, 또는 마지막에하지 않을 경우 : tac
, sort
그리고 uniq
적절한 도구가 될하지 않을 것입니다.
다음을 사용하는 솔루션은 다음과 같습니다 awk
.
$ awk 'function push(a,e) { a[length(a)+1] = e } BEGIN {split("", lines); to_replace="toreplace"; exists=0} {if ($0 ~ "^\\[ [0-9]+%"){ll=$0; if (exists <= 0) {exists++; push(lines,to_replace)}} else {push(lines, $0)}} END {for (e in lines){if (lines[e] == to_replace) {print ll} else {print lines[e]}}}' test.log
..........
[ 60% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
#### failed to build some targets (17:26 (mm:ss)) ####
읽을 수 있고 설명 된 버전 :
# a function to append an element to an array dynamically
function push(a,e) {
a[length(a)+1] = e
}
BEGIN {
split("", lines); # initializing an array
to_replace="toreplace"; # you can change the replace key if you want
exists=0
}
{
if ($0 ~ "^\\[ [0-9]+%"){ # matching all percentages/progression lines, regardless of their values ll=$0;
if (exists <= 0) {
exists++;
push(lines, to_replace)
}
} else {
push(lines, $0)
}
}
END {
for (e in lines) {
if (lines[e] == to_replace) {
print ll
} else {
print lines[e]
}
}
}
William Pursel 솔루션 과의 차이점 은 백분율이 증가 할 때입니다. 이 경우 동작의 차이점을 살펴 보겠습니다.
$ cat test.log
..........
[ 60% 60917/101076] AAPT2 compile ....
[ 60% 60918/101076] AAPT2 compile ....
[ 60% 60919/101076] AAPT2 compile ....
[ 61% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
#### failed to build some targets (17:26 (mm:ss)) ####
$ awk 'function push(a,e) { a[length(a)+1] = e } BEGIN {split("", lines); to_replace="toreplace"; exists=0} {if ($0 ~ "^\\[ [0-9]+%"){ll=$0; if (exists <= 0) {exists++; push(lines,to_replace)}} else {push(lines, $0)}} END {for (e in lines){if (lines[e] == to_replace) {print ll} else {print lines[e]}}}' test.log
..........
[ 61% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
#### failed to build some targets (17:26 (mm:ss)) ####
$ awk '$2 != n[2]{print p} {p = $0; split(p,n,FS)} END{print p}' test.log
..........
[ 60% 60919/101076] AAPT2 compile ....
[ 61% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
#### failed to build some targets (17:26 (mm:ss)) ####
따라서 백분율이 동일하지 않더라도 마지막 진행 라인 만 유지하려는 경우 또는 동일한 백분율을 가진 라인 만 여러 번 필터링하려는 경우 선택할 수 있습니다.
출력하려는 첫 번째 줄이로 시작하는 마지막 줄인 것이 확실하다면 파일의 시작부터 줄 바꿈 [
이 [
선행 된 마지막 줄 까지 기본적으로 모든 것을 단일로 바꿉니다 [
.
sed -z 's/.*\n\[/[/' file
...
샘플 입력의 시작 부분에 있는 줄이 더 많은 선행 [...] ...
줄을 나타낸다고 가정합니다 .
$ awk '/^\[/{p=$0 ORS; next} {print p $0; p=""}' build.log
[ 60% 60920/101076] AAPT2 compile ....
ninja: build stopped: subcommand failed.
21:41:22 ninja failed with: exit status 1
#### failed to build some targets (17:26 (mm:ss)) ####
이 가정이 잘못된 경우 질문을 수정하여 s가 아닌 대표 값만 있는 최소한의 완전 하고 검증 가능한 예 를 표시하십시오 ...
.