내 입력 파일:
{empty line}
Test #1
data
{empty line}
Test #2
data
{empty line}
Test #3
{empty line}
Test #4
data
{empty line}
Test #5
예상 출력:
1
2
4
간단한 bash 스크립트를 사용하여 각 테스트에서 사용할 수 있는 데이터가 있는 경우 일련번호(해시태그 뒤)를 어떻게 얻을 수 있나요?
편집: 각 테스트의 데이터에는 날짜, 시간, 차이 등과 같은 몇 가지 값이 포함되어 있습니다. 두 테스트 사이에 두 개 이상의 데이터 라인이 있습니다. 각 테스트 사이에는 빈 줄이 있습니다. "테스트" 숫자는 항상 1부터 시작하여 엄격하게 증가하는 양의 정수입니다.
답변1
이렇게 하면 됩니다:
awk -F ' #' '
function maybePrint() {
if (NR > 1 && NR > lastLine + 1) {print lastSeq}
}
$1 == "Test" {
maybePrint()
lastSeq = $2
lastLine = NR
}
END {
maybePrint()
}
' file
요구 사항을 변경하는 것은 좋지 않지만 퍼즐을 좋아하기 때문에 파일에 빈 줄이 있는 경우:
sed -n '
/^Test #/ {
s///
=
p
}
$=
' file \
| paste - - \
| awk -F '\t' '
NR > 1 && $1 - prevLine > ($2 ? 2 : 0) {print prev}
{prevLine = $1; prev = $2}
'
답변2
데이터에 해시태그가 없는 경우:
sed -n 'N;/#.*#/D;s/.*#//;P' file
더 명확한 옵션:
sed -nE 'N;/(.*#)[0-9]+\n\1/D;s/.*#//;P' file
패턴은 (.*#)[0-9]+\n\1
해시태그를 사용하여 중복 행을 추적합니다.
답변3
를 사용할 때 sed
일반적으로 N;P;D
모드와 예약된 공간 사용 중에서 선택합니다.
N;P;D
방법
N
이 방법을 사용하면 처음에 하나를 추가 하고 P
첫 번째 줄만 인쇄하고 D
첫 번째 줄을 삭제하여 새 루프를 시작하여 버퍼에 항상 두 개의 연속 줄을 유지할 수 있습니다 .
sed '$!N;/\ndata/!D;s/.*#//;P;D'
$!N
아직 마지막 줄이 아닌 경우 다음 줄을 추가하세요./\ndata/
두 번째 라인의 이중 라인과 일치하고data
,!
일치를 반전시킨 후D
버퍼의 두 번째 라인만으로 다음 루프를 시작합니다. 따라서 두 번째 줄이 시작하지 않으면data
다음 쌍으로 계속 진행하세요.- 여기에 도달하면 두 번째 줄이 로 시작한다는 것을 알 수 있으므로
data
그s/.*#//
전까지의 모든 내용은 삭제되고#
첫P
번째 줄은 인쇄되고(이제 숫자만 표시됨) 다음 루프의 첫 번째 줄이 삭제됩니다( 여기에 있는D
두 줄에 유의하세요).data
경우 당신은 무엇을 해야할지 모르겠어요.
대기 공간 접근
이전 공간 에서 정보를 인쇄하려는 행을 유지 h
하되, 트리거하는 행에만 인쇄하십시오.
sed '/data/!{h;d;};x;s/.*#//'
/data/!
모두 포함되지 않은 주소data
를 입력h
하고d
출력 없이 다시 시작하려면 삭제하세요.- 여기에 있고
data
일치하는 경우 버퍼를 변경하여 저장된 라인을 패턴 공간으로 가져오고x
내용을 제거한 후 기본 출력을 통해 결과를 인쇄합니다.#
s/.*#//
답변4
awk '{a[++i]=$0}/data/{for(x=NR-1;x<=NR;x++)print a[x]}' file| awk -F "#" '/Test/{print $2}'
산출
1
2
4