我要做这样的事
for (( every occurrence of the word TRAP-TYPE in a file ))
do
desc="$(< inputfile awk '/DESCRIPTION/ {getline; gsub(/^\s*"/, ""); gsub(/"\s*$/, ""); print}')"
casenum="$(< inputfile awk '/::=/ {gsub(/^\s*::=\s*/, ""); gsub(/\s*$/, ""); print}')"
echo $desc $numvar $casenum
done
它将搜索所有出现的TRAP-TYPE
。任何语言都可以!
输入
sCSISmart20 TRAP-TYPE
ENTERPRISE cyclone
描述
“Aspi:无法读取文件,服务器硬盘可能有问题”
--#TYPE “Aspi:无法读取数据库文件”
--#SUMMARY “ASPI:无法读取文件,服务器硬盘可能有问题”
--#ARGUMENTS {}
--#SEVERITY WARNING
--#TIMEINDEX 100
--#STATE OPERATIONAL
--#HELP “scsismrt.hlp”
--#HELPTAG 124
::= 124sCSISmart21 TRAP-TYPE
ENTERPRISE cyclone
描述
“Aspi:数据库已损坏”
--#TYPE “Aspi:数据库已损坏”
--#SUMMARY “ASPI:数据库文件已损坏”
--#ARGUMENTS {}
--#SEVERITY WARNING
--#TIMEINDEX 100
--#STATE OPERATIONAL
--#HELP “scsismrt.hlp”
--#HELPTAG 125 ::= 125sCSISmart12 TRAP-TYPE
ENTERPRISE cyclone
VARIABLES {cycHostAdapterNumber、cycScsiTargetID、cycLun、cycVendor、cycProduct、cycSenseInfo}
描述
“HostAdapter# %d、TargetID %d、Lun# %d 在供应商 %s 产品 %s 上具有预测故障条件,其中感测信息 MSB(感测代码)、接下来的 8 位(感测代码 Qual)接下来的 8 位(添加感测代码 Qual)LSB(0000)%d”
--#TYPE “设备具有 SMART/预测故障事件”
--#SUMMARY “HostAdapter# %d、TargetID %d、Lun# %d 在供应商 %s 产品 %s 上具有预测故障条件,其中感测信息 %d”
--#ARGUMENTS {0,1,2,3,4,5}
--#SEVERITY INFORMATIONAL
--#TIMEINDEX 100
--#STATE操作
--#HELP“scsismrt.hlp”
--#HELPTAG 116
::= 116
输出
Aspi: unable to read the file server hard disk might have problems
124
Aspi: database is corrupted
125
抱歉造成误解。我被糟糕的网络连接困扰着。
答案1
工作正在进行中
提取数据本身很容易:
awk '{ if($0~/DESCRIPTION/){getline;print $0}; if($0~/::=/) print $2}' testfile
使用包含您发布的输入文本的测试文件运行该程序,将得到以下输出:
$ awk '{if($0~/DESCRIPTION/){getline;print $0}; if($0~/::=/) print $2}' testfile
"Aspi: unable to read the file server hard disk might have problems"
124
"Aspi: database is corrupted"
125
如果我们要在那里有多个文件,则可以像这样编辑代码:
$ awk 'FNR==1{print FILENAME"\n========"} { if($0~/DESCRIPTION/){getline;print $0}; if($0~/::=/) print $2}' *.test
file1.test
========
"Aspi: unable to read the file server hard disk might have problems"
124
"Aspi: database is corrupted"
125
file2.test
========
"Aspi: second file"
134
"Aspi: i love awk"
135
这只是为了提取数据。我将继续编辑此答案,以包括如何将提取的数据分配给变量。
一种方法是使用 awk 的system
函数,该函数允许使用 awk 传递的变量运行 shell 命令。在此函数中,命令必须在双引号内,而 awk 的内部变量则在引号外。例如:
awk '{ if($0~/DESCRIPTION/){getline;printf $0"|"}; if($0~/::=/) printf $2"\n"}' *.test | awk -F'|' '{ STRING=$1;NUM=$2; system("echo this is the NUMBER "NUM" and this is the TEXT "STRING) }'
输出:
this is the NUMBER 124 and this is the TEXT Aspi: unable to read the file server hard disk might have problems
this is the NUMBER 125 and this is the TEXT Aspi: database is corrupted
this is the NUMBER 134 and this is the TEXT Aspi: second file
this is the NUMBER 135 and this is the TEXT Aspi: i love awk
将输出分配给变量的一种可能方式是使用两个并行数组。
$ IFS="|"; STRING_ARRAY=($(awk ' /DESCRIPTION/ {getline;printf "%s|",$0}; /::=/ { printf $2"\n" }' trapfile.txt | awk -F'|' '{printf "%s|",$1}'))
$ echo ${STRING_ARRAY[*]}
"Aspi: unable to read the file server hard disk might have problems" "Aspi: database is corrupted" "Aspi: second file" "Aspi: i love awk"
在那里,我使用了内部字段分隔符 IFS|
并创建了字符串数组,如两个 awk 命令所处理的那样。现在 STRING_ARRAY 可以在 for 循环中使用。要将适当的数字输出到数组:
$ IFS="|"; NUMS_ARRAY=($(awk ' /DESCRIPTION/ {getline;printf "%s|",$0}; /::=/ { printf $2"\n" }' trapfile.txt | awk -F'|' '{printf "%s|",$2}'))
$ echo ${NUMS_ARRAY[*]}
124 125 134 135
现在我们有两个并行数组,每个索引都与任何文件中每次出现的字符串和数字匹配
请注意,第一个管道中的代码是相同的,因此我们可以通过制作 awk 脚本来简化它:
#!/usr/bin/awk -f
# Author: SergKolo
# Date: June 16,2015
# Written for: http://askubuntu.com/q/636705/295286
# Awk script to extract text
# between two specific strings
# in a file
{
if($0~/DESCRIPTION/)
{
getline;printf "%s|",$0
};
if($0~/::=/) { printf $2"\n" }
}
将该脚本保存在名为 的文件中chmod +x scriptname.awk
。现在那些长命令简化为:
$ IFS="|"; LINES_ARRAY=($(trap-script.awk trapfile.txt | awk -F'|' '{printf "%s|",$1}' ))
和
$ IFS="|"; NUMBERS_ARRAY=($(trap-script.awk trapfile.txt | awk -F'|' '{printf "%s|",$2}' ))
笔记:因为从我们在评论中的对话中可以看出,您的某些文件包含具有%d
和%s
格式 , 字符的行,因此我printf "%s|",$0
出于某种原因在代码中包含了喜欢。当 printf 函数扩展行 $0 并看到这些格式字符时,它会假定必须输入它们,而不是将其视为一个长字符串。printf "%s|",$0
允许将这些 %d 字符视为文本,而不是需要输入的内容。
答案2
另一个 awk 解决方案:
$ gawk -F '\n *' -v RS="::=[^\n]*\n*" '{gsub(/[^0-9]/,"", RT); printf "%s\n%s\n", $4, RT}' foo
"Aspi: unable to read the file server hard disk might have problems"
124
"Aspi: database is corrupted"
125
文本自然地分成了记录,但记录分隔符并不十分直接。它可能是两个连续的换行符。我决定使用记录中的最后一个字段 ( ::= ...
),后面跟着任意多个换行符,作为记录分隔符。
然后,为了按字段进行拆分,我使用了一个换行符,后面跟着任意多个空格。之后,只需打印第四个字段,并从记录分隔符文本 ( RT
) 中提取数字即可。由于此解决方案使用RT
,因此它仅适用于 GNU awk。
答案3
在您的场景中,可以使用 awk、grep 和 sed 查找单词的出现;但您必须在 bash 脚本中使用一些 case 语句和迭代来将它们括起来。这是可以做到的。编写 Perl、Python、Java 或 C++ 程序似乎是更好的方法。
我刚刚为你写了这个。这是一个 c++ 程序。将下面的程序复制并粘贴到 gedit 中。将其保存为 findword.cpp。注意:你需要 build-essential 来编译它。
:~$ sudo apt-get install build-essential -y
:~$ g++ -o findword findword.cpp
该程序:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <locale>
using namespace std;
int main()
{
string wordhold = "";
int index;
string line;
string trptype = "TRAP-TYPE";
ifstream infile;
infile.open("Yourfile.txt"); // change Yourfile.txt to the name of the file
while ( getline(infile, line) ) {
index = line.find('\n');
string holdword = line.substr(0,index);
wordhold = holdword;
if ( wordhold.compare(wordhold.size(),9,trptype) == 0 ) {
system("Execute the command you want inside the quotes");
wordhold = "";
}
else {
wordhold = "";
}
}
infile.close();
cout << "The file is closed\nDone" << endl;
return 0;
}
通过复制条件语句(if)中的系统函数,您可以运行多个命令。
要运行该程序,请进入您编译的目录并从命令行执行它。
:~$ ./findword
祝你好运。
答案4
我的awk
版本:
awk '/TRAP-TYPE/ {traptype=1}; traptype && /DESCRIPTION/ {getline; gsub(/^ +/, "", $0); gsub(/^\"/, "", $0); gsub(/\"\s+$/, "", $0); print}; traptype && /::=/ {print $2}' testfile
或更具体
awk '/sCSISmart.*TRAP-TYPE/ {traptype=1}; traptype && /DESCRIPTION/ {getline; gsub(/^ +/, "", $0); gsub(/^\"/, "", $0); gsub(/\"\s+$/, "", $0); print}; traptype && /::=/ {print $2}' testfile
输入
testfile
sCSISmart20 TRAP-TYPE
ENTERPRISE cyclone
DESCRIPTION
"Aspi: unable to read the file server hard disk might have problems"
--#TYPE "Aspi: unable to read the database file"
--#SUMMARY "ASPI: unable to read the file, server hard disk may have problems"
--#ARGUMENTS {}
--#SEVERITY WARNING
--#TIMEINDEX 100
--#STATE OPERATIONAL
--#HELP "scsismrt.hlp"
--#HELPTAG 124
::= 124
sCSISmart21 TRAP-TYPE
ENTERPRISE cyclone
DESCRIPTION
"Aspi: database is corrupted"
--#TYPE "Aspi: database is corrupted"
--#SUMMARY "ASPI: database file is corrupted"
--#ARGUMENTS {}
--#SEVERITY WARNING
--#TIMEINDEX 100
--#STATE OPERATIONAL
--#HELP "scsismrt.hlp"
--#HELPTAG 125
::= 125
输出
Aspi: unable to read the file server hard disk might have problems
124
Aspi: database is corrupted
125
独立输出
awk '/TRAP-TYPE/ {traptype=1}; traptype && /DESCRIPTION/ {getline; gsub(/^ +/, "", $0); gsub(/^\"/, "", $0); gsub(/\"\s+$/, "", $0); print;}' testfile
Aspi: unable to read the file server hard disk might have problems
Aspi: database is corrupted
awk '/sCSISmart.*TRAP-TYPE/ {traptype=1}; traptype && /::=/ {print $2}' testfile
124
125