파일의 일부 읽기

파일의 일부 읽기

다음과 같은 구조의 파일이 있습니다.

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:]]/.424242421

범위 내에서 /^[[: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:]]*//'@및 로 시작하는 빈 줄을 제거합니다 .

관련 정보