다음 문자열이 있습니다.
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
none65@pci0:2:0:2: class=0x080100 rev=0x00 hdr=0x00 vendor=0x1453
vendor = 'MicSystem'
device = 'interface'
class = base peripheral
subclass = DMA controller
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
"class = Base Peripheral" 앞에 3줄, 그 뒤에 1줄을 삭제해야 합니다. 예를 들면 다음과 같습니다.
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
나는 이것을 할 수 없었습니다. 이것은 FreeBSD 운영 체제에서 수행되었습니다.
답변1
답변2
이 시도 awk
:
awk '
FNR==NR && /class[[:blank:]]*=[[:blank:]]*base peripheral/{x=NR; nextfile;}
FNR!=NR && (FNR < x-3 || FNR > x+1)
' file file
file
두 번 먹이세요 awk
. 처음에는 해당 행을 찾습니다(여러 개가 있는 경우 첫 번째 행만 일치합니다!). 두 번째로 생략할 줄을 제외한 줄을 인쇄합니다.
명령 출력과 함께 사용하려면 다음을 사용하십시오.
awk '...' <(command) <(command)
또는
output="$(command)"
awk '...' <(printf '%s' "$output") <(printf '%s' "$output")
답변3
가장 간단한 방법은 아마도 다음과 같을 것입니다. 모든 Unix 시스템의 모든 쉘에서 awk를 사용하는 것입니다:
$ cat tst.awk
$0 ~ re {
for (i=(NR-b); i<=(NR+a); i++) {
skip[i]
}
}
{ lines[NR] = $0 }
END {
for (i=1; i<=NR; i++) {
if ( !(i in skip) ) {
print lines[i]
}
}
}
$ awk -v b=3 -v a=1 -v re='class[[:space:]]*=[[:space:]]*base peripheral' -f tst.awk file
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453 device=0xa2d2 subvendor=0x1453 subdevice=0x0008
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453 device=0xa2d2 subvendor=0x1453 subdevice=0x0008
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
입력이 셸에 저장되지 않고 파이프에서 나오는 경우 whatever | awk -v ... -f tst.awk
입력을 스크립트에 전달하는 모든 작업을 실행하거나 수행하십시오.
위의 솔루션과 마찬가지로 ed
전체 입력이 메모리로 읽혀지지만 입력 길이가 수억 줄이 아닌 경우에는 문제가 되지 않습니다. 이것이 실제로 그렇다면 b
현재 행이 정규식과 일치하지 않을 때 항상 배열의 첫 번째 요소를 인쇄하도록 크기 배열인 스크롤 버퍼를 구현할 수 있습니다. 그러나 이 경우 작성하는 데 더 많은 생각이 필요하고 작성하기가 더 어렵습니다. 겹치는 범위를 처리합니다.
답변4
문제는 이 행 앞뒤에 너무 많은 행을 삭제하는 것으로 설명되지만 이러한 의도된 편집의 효과는 "속성이 class
해당 값을 갖는 항목 삭제 base peripheral
"라는 더 높은 수준의 의미를 갖는다는 것이 분명합니다.
더 큰 문서의 구조와 관련된 이러한 유형의 변환 작업에 매우 적합한 언어가 있습니다.TxR.
다른 사람이 이해하기 쉬운 코드를 사용하여 필드 추출을 자세히 수행하거나 17개월 후에 귀하가 이해할 수 있도록 할 수 있습니다.
@(repeat)
@addr: class=0x@cl rev=0x@rev hdr=0x@hdr vendor=0x@ven
vendor = '@vendor'
device = '@device'
class = @class
subclass = @subclass
@ (require (nequal class "base peripheral"))
@ (output)
@addr: class=0x@cl rev=0x@rev hdr=0x@hdr vendor=0x@ven
vendor = '@vendor'
device = '@device'
class = @class
subclass = @subclass
@ (end)
@(end)
달리기:
$ txr data.txr data
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
core1@pci0:2:0:1: class=0x020000 rev=0x00 hdr=0x00 vendor=0x1453
vendor = 'MicSystem'
device = 'controller'
class = network
subclass = ethernet
여기서 패턴 일치 어설션은 @(require expr)
false인 경우 불필요한 항목을 제거합니다 expr
.
필터링을 임의로 복잡하게 만들고 필요에 따라 출력 형태를 쉽게 변경할 수 있습니다. 내장된 TXR Lisp 언어에는 마법 같은 초능력도 있습니다.