如何从文本块中提取特定行并将其存储到字符串变量中?

时间:2017-07-11 06:21:30

标签: bash

[Bash Scripting] - 我正在使用LG设备而我正在尝试获取连接的设备ID字符串。我已经弄清楚如何连接字符串,但我无法从整体输出中提取字符串。从引导加载程序,我运行 fastboot oem device-id 并获得这样的输出。 “|”之后的一切实际上已经输了,我只包括“#|”作为行引用。

1 | ...
2 | (bootloader) ----------------------------------
3 | (bootloader) Device-ID
4 | (bootloader) ABCDEFGH12345678ABCDEFGH12345678
5 | (bootloader) 87654321HGFEDCBA87654321HGFEDCBA
6 | (bootloader) ----------------------------------
7 | OKAY [  0.070s]
8 | finished. total time: 0.070s

似乎 fastboot oem device-id 有点受限制。在命令中使用grep只显示相同的内容。 ( fastboot oem device-id | grep bootloader -m 2 )这应该只显示前两行(示例)。我还尝试将所有内容输出到外部文本文件(并从那里开始工作),但它创建了一个文本空白文件。 ( fastboot oem device-id>> test.txt

理想情况下,我想提取第4行和第5行的内容,并将它们分别存储在单独的字符串变量中 - stringA stringB 。字符串A和B应输出以下内容

(stringA) <-- "(bootloader) ABCDEFGH12345678ABCDEFGH12345678" (Line 4)
(stringB) <-- "(bootloader) 87654321HGFEDCBA87654321HGFEDCBA" (Line 5)

然后我会像这样连接它们。

echo "Device ID:  $(stringA:13:32)$(stringB:13:32)"

从第13栏开始(上图)将排除(引导程序)_ 部分并仅保留所需的字符串。最后,echo(上图)的输出应如下所示。

Device ID:  ABCDEFGH12345678ABCDEFGH1234567887654321HGFEDCBA87654321HGFEDCBA

奇怪的是,我能够使用不同的fastboot命令( fastboot devices )完成上述所有操作。 还有哪些方法可以从第4行和第5行(上面)中提取字符串并将它们存储到两个单独的字符串变量中?

2 个答案:

答案 0 :(得分:2)

使用awk

$ fastboot oem device-id | awk 'NR==4{a=$2} NR==5{b=$2; printf "Device ID:  %s%s\n",a,b; exit}'
Device ID:  ABCDEFGH12345678ABCDEFGH1234567887654321HGFEDCBA87654321HGFEDCBA

工作原理:

  • NR==4{a=$2}

    当我们到达第四行时,将第二个字段保存在变量a中。

  • NR==5{b=$2; printf "Device ID: %s%s\n",a,b; exit}

    当我们到达第五行时,将第二个字段保存在变量b中并写入输出行。

使用sed

$ fastboot oem device-id | sed -n 's/.* //; 4h; 5{H; x; s/\n//; s/^/Device ID:  /p}'
Device ID:  ABCDEFGH12345678ABCDEFGH1234567887654321HGFEDCBA87654321HGFEDCBA

工作原理:

  • -n

    除非我们明确要求,否则告诉sed不要打印任何内容。

  • s/.* //

    查找所有字符,包括该行的最后一个空格并删除它们。

  • `4H

    如果我们在第四行,请将剩下的内容保存到保留空间。

  • 5{H; x; s/\n//; s/^/Device ID: /p}

    如果我们在第五行,请将该行的左侧附加到保留空间(H)。使用模式空间(x)交换保留空间。删除换行符任何换行符(s/\n//)。将字符串Device ID:添加到模式空间的开头并打印它(s/^/Device ID: /p)。

使用bash和grep

$ fastboot oem device-id | grep -oE '[[:alnum:]]{32}$' | { read a; read b; echo "Device ID:  $a$b"; }
Device ID:  ABCDEFGH12345678ABCDEFGH1234567887654321HGFEDCBA87654321HGFEDCBA

工作原理:

  • grep -oE '[[:alnum:]]{32}$'

    如果来自fastboot的行以32个字母数字字符结尾,则打印这些字符。

    更详细地说,-o选项告诉grep仅打印一行的匹配部分。 -E告诉grep使用扩展正则表达式。 [[:alnum:]]{32}匹配32个字母数字字符。 $仅在该行的末尾匹配。

  • read a; read b; echo "Device ID: $a$b";

    grep的第一个输出行被读入变量a。第二个输出行被读入变量b。然后,所需的行回显到标准输出。

答案 1 :(得分:0)

如果输出文本文件output.txt,例如:

user@host:~$ cat output.txt 
...
(bootloader) ----------------------------------
(bootloader) Device-ID
(bootloader) ABCDEFGH12345678ABCDEFGH12345678
(bootloader) 87654321HGFEDCBA87654321HGFEDCBA
(bootloader) ----------------------------------
OKAY [  0.070s]
finished. total time: 0.070s

以下命令:

cat output.txt | sed -n '4,5p' | awk '{print $2}' | tr -d '\n'
  • 保留第4和第5行
  • 仅保留第二列
  • 删除换行符

因此它最终给出了:

  

ABCDEFGH12345678ABCDEFGH1234567887654321HGFEDCBA87654321HGFEDCBA

当然,这个也适用:

cat output.txt | sed -n '4,5p' | cut -d\  -f2 | tr -d '\n'