다음과 같은 구조의 파일이 있습니다.
4168 Targus
1010 Wireless Compact Laser Mouse
4242 USB Design by Example
4201 Buttons and Lights HID device
4220 Echo 1 Camera
4255 GoPro
1000 9FF2 [Digital Photo Display]
2000 HD2-14 [Hero 2 Camera]
4317 Broadcom Corp.
0700 U.S. Robotics USR5426 802.11g Adapter
0701 U.S. Robotics USR5425 Wireless MAXg Adapter
0711 Belkin F5D7051 v3000 802.11g
0720 Dynex DX-BUSB
0721 Dynex DX-EBUSB
4348 WinChipHead
5523 USB->RS 232 adapter with Prolific PL 2303 chipset
5537 13.56Mhz RFID Card Reader and Writer
5584 CH34x printer adapter cable
4572 Shuttle, Inc.
4572 Shuttle PN31 Remote
여기서 각 부분은 공백이 아닌 문자로 구분됩니다. 파일의 각 섹션의 시작 문자와 줄 번호를 모릅니다.
Bash 또는 Python 3에서 두 부분 사이의 줄을 읽는 방법은 무엇입니까?
위의 예에서 첫 번째 부분은 라인 4168이며 다음 라인 앞 라인까지입니다(공백이 아닌 문자로 시작). 첫 번째 부분에는 다음 줄이 있습니다.
1010 Wireless Compact Laser Mouse
두 번째 부분에는 다음이 포함됩니다.
4201 Buttons and Lights HID device
4220 Echo 1 Camera
주어진 입력으로 부분 선택이 수행됩니다. 예를 들어4242입력하세요. 읽어야 할 부분은 다음과 같습니다.
4201 Buttons and Lights HID device
4220 Echo 1 Camera
라인 번호를 모른다는 점에 유의하세요.4242.
답변1
num=4242
sed -n '
/^'"$num"'\b/,/^[^[:blank:]]/{
/^[[:blank:]]/ {s/^[[:blank:]]*//;p}
}' data_file
GNU 4.7에서 테스트되었습니다 sed
.
변수가 확장되면 코드 4242
에 나타납니다 . sed
맨 처음에 있는 완전한 단어(예: 차별화)인 줄부터 선행 공백(탭 또는 공백)이 없는 첫 번째 줄까지의 범위를 정의합니다 /^4242\b/,/^[^[:blank:]]/
.4242
42421
범위 내에서 /^[[:blank:]]/
공백( )으로 시작하는 줄의 선행 공백이 제거되고( s/^[[:blank:]]*//
) 인쇄됩니다( p
).
노트:
- 두 개 이상의 부품이 인식되면
4242
해당 행이 다른 부품에 속한다는 표시 없이 모든 부품에서 행을 가져옵니다. (num=…; sed …)
현재 셸에서 변수를 설정(또는 변경) 하지 않으려면 하위 셸( )에서 코드를 실행하세요 .num
답변2
강제 awk
솔루션:
awk -v sect="4242" '$0~/^[[:digit:]]/ {if ($1==sect) {p=1;next} else p=0} p' input.txt
- 이 부분은
awk
구문을 통해 변수로 지정됩니다.sect
-v
- 숫자로 바로 시작하는 행이 발견되면 해당 행은 섹션의 시작으로 간주됩니다. 섹션 번호가 원하는 섹션과 일치하면
p
플래그("인쇄"용)를 설정1
하지만 다음 줄로 처리를 건너뜁니다(그래서 섹션의 시작 부분을 인쇄하지 않습니다). 섹션 번호가 일치하지 않으면 플래그를 로 설정합니다0
. p
인 경우에만 현재 줄을 인쇄합니다1
.
출력에서 선행 공백을 제거하려면 다음과 같이 프로그램을 수정하십시오.
awk -v ... '$0~/^[[:digit:]]/ {if ($1==sect) {p=1;next} else p=0}
p{sub(/^[[:space:]]+/,""); print}' input.txt
답변3
@
나는 파일 내용에 아무것도 없다고 가정하고 이 솔루션을 제안합니다 .
$ sed -e 's/^\([0-9]\)/@\1/' -n -e '/@4317/,/@/p' file | sed -e '/^@/d' -e 's/^[[:blank:]]*//'
0700 U.S. Robotics USR5426 802.11g Adapter
0701 U.S. Robotics USR5425 Wireless MAXg Adapter
0711 Belkin F5D7051 v3000 802.11g
0720 Dynex DX-BUSB
0721 Dynex DX-EBUSB
's/^\([0-9]\)/@\1/'
교체의 시작 라인 번호입니다@
.'/@4317/,/@/p'
둘 중 하나@
(주어진 식별자)를 선택합니다.sed -e '/^@/d' -e 's/^[[:blank:]]*//'
@
및 로 시작하는 빈 줄을 제거합니다 .