有人能帮帮我吗?
我正在尝试打印bash脚本的命令输出,以检查SuSE产品注册
命令输出(/usr/bin/SUSEConnect --status-text)
Installed Products:
------------------------------------------
Desktop Applications Module
(sle-module-desktop-applications/15.2/x86_64)
Registered
------------------------------------------
Server Applications Module
(sle-module-server-applications/15.2/x86_64)
Registered
------------------------------------------
Basesystem Module
(sle-module-basesystem/15.2/x86_64)
Registered
------------------------------------------
Legacy Module
(sle-module-legacy/15.2/x86_64)
Not Registered
------------------------------------------
字符串
我只是过滤了一下
sudo /usr/bin/SUSEConnect --status-text|sed -r '/^\s*$/d'|tr -d '[:blank:]'|grep -Ev "^-|InstalledProducts"
DesktopApplicationsModule
(sle-module-desktop-applications/15.2/x86_64)
Registered
ServerApplicationsModule
(sle-module-server-applications/15.2/x86_64)
Registered
BasesystemModule
(sle-module-basesystem/15.2/x86_64)
Registered
LegacyModule
(sle-module-legacy/15.2/x86_64)
NotRegistered
型
但我想删除行(*)并打印如下
Installed Products : DesktopApplicationsModule Registered
ServerApplicationsModule Registered
BasesystemModule Registered
LegacyModule NotRegistered
型
谢谢你,
4条答案
按热度按时间wgx48brx1#
使用任何POSIX
awk
和column
:字符串
型
如果您愿意,可以选择只打印某些列而不是所有列,例如:
型
oogrdqng2#
下面的代码应该适用于任何POSIX
awk
(使用GNUawk
和macOS附带的BSDawk
进行了测试):字符串
根据实际数据调整输出字段宽度(25,35)。
说明:当
RS
被设置为空字符串时,记录分隔符是一个或多个空行。所有记录都经过预处理(gsub(/^[[:space:]]*|[[:space:]]*(\n.*)?$/,"")
),只保留第一行,并删除前导和尾随空格。对于记录2,5,8...(应用程序名称)我们将记录存储在变量p
中。对于记录3,6,9...(注册状态)我们打印当前应用程序的输出:h
中的标题,在25个字符上左对齐,p
中的应用程序名称,左对齐35个字符,$0
)。在第一个
printf
之后,我们清除header(h=""
)。如果你更喜欢自动计算输出字段宽度,我们必须等到输入结束才能打印,因为我们需要知道最长的应用程序名称:
型
注意:正如其他答案所建议的那样,我们也可以使用
column
实用程序进行最终格式化,但我们需要为column
的输入选择一个字段分隔符,这在您的主输入中找不到。除非您知道这样一个分隔符,并且100%确定在主输入中找不到它,否则只使用awk
进行整个操作可能会更安全一些。vfwfrxfs3#
我已经将你的命令输出复制到文件'f'中做了一些测试,你不需要
tr
和grep
,sed
就可以删除所有不必要的东西:字符串
现在,让我们使用
printf
来打印:型
看起来很酷),并使它成为你想要的方式让我们这样做:
型
测试结果:
型
更新,这里是sed规则
/^\s*$|^-|\(.*\)|^Ins/d;s/ //g
的解释。有2个sed命令,通过'分隔;第一个/.../d
-删除命令和第二个s///g
-替代命令。让我们仔细看看它们:/^\s*$|^-|\(.*\)|^Ins/d
此命令由几个正则表达式模式组成,以匹配不需要的字符串,所有匹配的字符串将被删除:^\s*$
-将匹配“空格”字符串^-
-将匹配从'-'开始的字符串\(.*\)
-将匹配带有'()'的字符串^Ins
-将匹配以'Ins'开头的字符串s/ //g
用空替换所有空格(删除空格)我添加了这个,因为OP在没有空格的描述中具有所需的输出。但是根据OP的注解空间必须保留,让我们这样做。看起来我们只需要删除第二个sed命令
s/ //g
?不,这会破坏输出:型
相反,我们需要将其更改(替换)为某种模式,例如
_SPS_
,以在数组中创建弹出项数量,然后将其更改回空格。脚本将是这样的:型
请注意,现在我将
${arr[@]:i:2}
Package 在"
中,这是必要的,因为现在我们有了带有空格的项。下面是输出:型
aor9mmx14#
通过在
sed
中增加一点逻辑来缩短管道。您不需要单独调用
tr
和grep
。字符串
或者,折叠成一条更密集的单线,
型
为了查看它的实际效果,我只是手动生成了示例的输出:
型
只是有点-
-n
不打印,除非我这么说。/Installed Products:/h
将这一行放入h
旧缓冲区(擦除任何以前的内容)/Module$/H
add 这一行到H
旧缓冲区/Registered/{
在这一行打开一个命令块:H
添加到H
旧缓冲区g
用保持缓冲区内容替换模式缓冲区s/ //g
删除所有空格s/\n/\t/g
用制表符替换换行符p
p
打印编辑的图案缓冲区z
z
ap(空)模式缓冲区- *GNU特定 *x
e
xchange the pattern and hold buffers (empties the hold)
}'关闭代码块如果不使用GNU
sed
,请将z
替换为s/.//g
,您可能需要将所有这些命令放在不同的行上,而不是仅用分号分隔。如果您想包含名称,请添加
-E
并将/Module$/H
更改为/Module$|[(]/H
-型
正如Renaud指出的,使用
column
确实需要在输入中使用字段分隔符。在玩这个的时候,我让它使用回车(\r
)和铃声字符(\a
)。YMMV