Я должен сделать что-то вроде этого
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: не мог считать файл, жесткий диск сервера может иметь проблемы"
- #ARGUMENTS {}
- ПРЕДУПРЕЖДЕНИЕ #SEVERITY
- #TIMEINDEX 100
- ОПЕРАЦИОННЫЙ #STATE
- #HELP "scsismrt.hlp"
- #HELPTAG 124
:: = 124ТИП ПРЕРЫВАНИЯ sCSISmart21
Циклон ПРЕДПРИЯТИЯ
ОПИСАНИЕ
"Aspi: база данных повреждается"
- #TYPE "Aspi: база данных повреждается"
- #SUMMARY "ASPI: файл базы данных повреждается"
- #ARGUMENTS {}
- ПРЕДУПРЕЖДЕНИЕ #SEVERITY
- #TIMEINDEX 100
- ОПЕРАЦИОННЫЙ #STATE
- #HELP "scsismrt.hlp"
- #HELPTAG 125:: = 125ТИП ПРЕРЫВАНИЯ sCSISmart12
Циклон ПРЕДПРИЯТИЯ
ПЕРЕМЕННЫЕ {cycHostAdapterNumber, cycScsiTargetID, cycLun, cycVendor, cycProduct, cycSenseInfo}
ОПИСАНИЕ
"HostAdapter# %d, TargetID %d, Lun# %d имеет Прогнозирующее Состояние отказа на поставщике %s продукт %s с информацией о смысле MSB (код смысла), следующие 8 битов (смысл кодируют Квалификацию), следующие 8 битов (Добавьте, что смысл кодирует Квалификацию), LSB (0000) %d"
- #TYPE "Устройство имеет событие отказа SMART/Predicictive"
- #SUMMARY "HostAdapter# %d, TargetID %d, Lun# %d имеет Прогнозирующее Состояние отказа на поставщике %s продукт %s с senseinfo %d"
- #ARGUMENTS {0,1,2,3,4,5}
- ИНФОРМАЦИОННЫЙ #SEVERITY
- #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
Извините за недоразумение. Я заполоняюсь плохим интернет-соединением.
ПРОИСХОДЯЩАЯ РАБОТА
Извлечение самих данных легко:
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
Это только для извлечения данных. Я продолжу редактировать этот ответ, чтобы включать, как можно присвоить извлеченные данные переменным.
Один подход должен использовать awk's 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
Один возможный способ присвоить вывод переменным был бы с двумя массивами parralel.
$ 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 может использоваться в для цикла. Производить соответствующие числа к массиву:
$ 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 символы как текст, не как что-то, что должно ввести.
Другое 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-только.
В Вашем сценарии происшествия слова могли быть найдены с awk, grep, и sed; но необходимо было бы упаковать тех в сценарии удара с некоторыми оператор выбора и повторение. Это может быть сделано. Писание 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;
}
Вами может выполнить несколько команд путем дублирования системной функции, которая находится в операторе условия (если).
Для запущения программы вводят каталог, в котором Вы скомпилировали, и выполните его из командной строки.
:~$ ./findword
Удача.
Используя awk
:
< inputfile awk '/DESCRIPTION/ {getline; sub(/^ *"/,""); sub(/"$/,""); print}; /::=/ {sub(/::= */,""); print}'
Расширенная версия:
< inputfile awk '
/DESCRIPTION/ {
getline;
sub(/^ *"/,"");
sub(/"$/,"");
print
};
/::=/ {
sub(/^::= */,"");
print
}
'
/DESCRIPTION/
: выбирает только записи, содержащие строку DESCRIPTION
getline
: пропускает первую записьsub(/^ *"/,"")
: замените строкой, составленной любым количеством пробелов, сопровождаемых a "
символ, в начале строки, с пустой строкойsub(/"$/,"")
: замена a "
символ, в конце строки, с пустой строкой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