私はこのようなことをするつもりです
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トラップタイプ
エンタープライズサイクロン
説明
「Aspi:ファイルサーバーのハードディスクを読み取れません。問題が発生する可能性があります」
-#TYPE "Aspi:データベースファイルを読み取れません"
-#SUMMARY "ASPI:ファイルを読み取れません。サーバーのハードディスクに問題がある可能性があります"
-#引数{}
-#重大度の警告
-#TIMEINDEX 100
-#STATE OPERATIONAL
-#HELP "scsismrt.hlp"
-#HELPTAG 124
:: = 124sCSISmart21トラップタイプ
エンタープライズサイクロン
説明
「Aspi:データベースが破損しています」
-#TYPE "Aspi:データベースが破損しています"
-#SUMMARY "ASPI:データベースファイルが破損しています"
-#引数{}
-#重大度の警告
-#TIMEINDEX 100
-#STATE OPERATIONAL
-#HELP "scsismrt.hlp"
-#HELPTAG 125 :: = 125sCSISmart12トラップタイプ
エンタープライズサイクロン
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で予測障害状態があります"
-#引数{0,1,2,3,4,5}
-#重大度
-#TIMEINDEX 100
-#STATE OPERATIONAL
-#HELP "scsismrt.hlp"
-#HELPTAG 116
:: = 116
出力
Aspi: unable to read the file server hard disk might have problems
124
Aspi: database is corrupted
125
誤解してすみません。私はインターネット接続の悪さに悩まされています。
進行中
データ自体の抽出は簡単です。
awk '{ if($0~/DESCRIPTION/){getline;print $0}; if($0~/::=/) print $2}' testfile
投稿した入力テキストを含む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
_
これはデータを抽出するためだけのものです。この回答を編集し続けて、抽出したデータを変数に割り当てる方法を含めます。
1つの方法は、awkのsystem
関数を使用することです。これにより、awkから渡された変数を使用してシェルコマンドを実行できます。この関数では、コマンドは二重引用符内にあり、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
_
出力を変数に割り当てる1つの可能な方法は、2つの並列配列を使用することです。
_$ 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 _|
_を使用して、2つの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
_
これで2つの並列配列ができました。各インデックスは文字列に一致し、ファイル内の各オカレンスからの番号に一致します
最初のパイプのコードは同じなので、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を展開し、それらのフォーマット文字を検出すると、1つの長い文字列として扱うのではなく、それらの入力が必要であると想定します。 _printf "%s|",$0
_を使用すると、これらの%d文字を、入力が必要なものとしてではなく、テキストとして扱うことができます。
別の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
テキストは自然にレコードに分割されますが、レコードの区切り記号はそれほど単純ではありません。 2つの連続した改行になる可能性があります。レコードの最後のフィールド(::= ...
)の後に、レコードセパレータとして任意の数の改行が続きます。
次に、フィールドを分割するために、改行の後に任意の数のスペースを続けました。その後は、4番目のフィールドを印刷し、レコード区切りテキスト(RT
)から数値を抽出するだけです。このソリューションはRT
を使用するため、GNU awkのみです。
あなたのシナリオでは、Wordの出現はawk、grep、sedで見つけることができます。しかし、いくつかのcaseステートメントと反復を使用して、bashスクリプトでそれらを大文字にする必要があります。できます。 Perl、Python、Java、またはC++プログラムを書くことは、それを行うためのより良い方法のようです。
私はあなたのためにこれを書いただけです。これはc ++プログラムです。以下のプログラムをコピーしてgeditに貼り付けます。 findword.cppとして保存します。注:コンパイルするには、必須のビルドが必要です。
:~$ 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
幸運を。
awk
の使用:
_< inputfile awk '/DESCRIPTION/ {getline; sub(/^ *"/,""); sub(/"$/,""); print}; /::=/ {sub(/::= */,""); print}'
_
拡張バージョン:
_< inputfile awk '
/DESCRIPTION/ {
getline;
sub(/^ *"/,"");
sub(/"$/,"");
print
};
/::=/ {
sub(/^::= */,"");
print
}
'
_
/DESCRIPTION/
_:文字列DESCRIPTION
を含むレコードのみを選択しますgetline
:最初のレコードをスキップしますsub(/^ *"/,"")
:行の先頭にある任意の数のスペースとそれに続く_"
_文字で構成される文字列を空の文字列に置き換えますsub(/"$/,"")
:行の最後の_"
_文字を空の文字列に置き換えますprint
:レコードを出力します/::=/
_:文字列_::=
_を含むレコードのみを選択しますsub(/^::= */,"")
:行の先頭にある_::=
_とそれに続く任意の数のスペースで構成される文字列を空の文字列に置き換えますprint
:レコードを出力します私の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
_