У меня есть файл, который нужно обработать и получить из него несколько записей. Формат файла такой:
Пример ввода:
String1:"Hello"
String2:"World"
String3:"Question"
End
String1:"HelloAgain"
String5:"Answer"
End
String1:"NewEntry"
String2:"Foo"
String5:"NewFile"
End
Скрипт будет выполнять итерации и пытаться найти Строку1 и вывести ее, если Строка2 также присутствует в этом блоке, добавить ее к Строке1 и вывести.
Пример вывода:
Hello World
HelloAgain
NewEntry Foo
Мне нужно просмотреть каждый такой блок. Под блоком я понимаю содержимое между каждой строкой "End". У меня есть сценарий типа:
cat $1 | while read line
do
if [[ $line == "String1="* ]];
then
string1=$line
fi
if [[ $line == "String2="* ]];
then
string2=$line
fi
if [[ $line == "End" ]];
then
if [ $string1 ];
then
echo "string1/"$string1"
fi
if [ $string1 ] && [ $string2 ];
then
echo $string1" "$string2
fi
#Reset values
string1=''
string2=''
fi
done
Этот код работает хорошо, но обработка между этими блоками может стать более сложной, какой лучший способ итерации таких блоков и обработки записей этих блоков.
ПРИМЕЧАНИЕ: Файл является своего рода файлом свойств.
С учетом введенных вами данных и запрошенных выходных данных:
$ awk -F: '$0 == "End" { printf "\n" } $1 ~ /^String[12]$/ { gsub( /\"/, "", $2 ); printf( "%s ", $2)}' input
Hello World
HelloAgain
NewEntry Foo
perl -F':|"' -lane 'if ($out && $_ eq "End") {print "$out"; $out=""};
$out = $F[2] if ($F[0] eq "String1");
$out.= $F[2] if ($out && $F[0] eq "String2")' input.txt
Этот perl-скрипт использует либо :
, либо "
в качестве разделителя полей, чтобы избежать необходимости удалять из вывода двойные -кавычки. это означает, что нам нужно извлечь третье поле, а не второе, поскольку теперь между первым :
и "
есть пустое поле. Массивы Perl основаны на нуле -, так что $F[2]
.
Он печатает вывод только для записи ("блока" ), если есть что печатать, либо String1 сама по себе , либо String1 и String2 присутствуют -, т.е. t печатать пустые строки для не соответствующих -записей.
Вот тот же алгоритм вawk
:
awk -F':|"' 'out && $0 == "End" { print out; out="" };
$1 == "String1" { out=$3 };
out && $1 == "String2" { out = out$3 }' input.txt