ファイルの一部を読む

ファイルの一部を読む

次の構造のファイルがあります。

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で2つの部分の間の行を読み取るには?

上記の例では、最初の部分は行4168で、次の行の前の行までです(空白ではなく文字で始まります)。最初の部分には次の行があります。

1010  Wireless Compact Laser Mouse

2番目の部分には以下が含まれます。

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:]]*//'@で始まる空白行を削除します。

関連情報