读取文件的部分

读取文件的部分

我有一个具有以下结构的文件:

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那么您将从所有这些部分获得行,而没有任何指示这些行来自不同的部分。
  • 在子 shell ( ) 中运行代码以避免在当前 shell 中(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仅当is时才打印当前行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:]]*//'删除以@和 开头的空白行。

相关内容