2015-09-22 3 views
-2

Привет У меня есть имя файла test.txtзначения GREP и перестановка файла

(standard input):8:  <property name="ProcedureName" value="abc"/> 
(standard input):7:   <property name="PackageName" value="123abc"/> 
(standard input):8:   <property name="ProcedureName" value="bac"/> 
(standard input):7:  <property name="PackageName" value="bac123"/> 
(standard input):8:  <property name="ProcedureName" value="cde"/> 
(standard input):7:  <property name="PackageName" value="cd123"/> 
(standard input):8:  <property name="ProcedureName" value="b4u"/> 
(standard input):7:  <property name="PackageName" value="b4u234"/> 

я должен ГРЭП только значение PackageName и procdeurename из этого файла в формате follwing: в о/р файл

abc/123abc 
bac/bac123 
cde/cd123 
b4u/b4u234 

попытался вырезать и AWK, но не смог получить, что

+2

Покажите нам свои попытки –

ответ

1

awk должны быть в состоянии сделать это для вас:

awk -F'"' 'BEGIN { OFS="/" } $2=="ProcedureName"{procedureName=$4} $2=="PackageName" { print procedureName,$4 }' yourfilename 

Это будет использовать двойную кавычку в качестве разделителя. Он проверяет строку «ProcedureName» в позиции 2 и сохраняет позицию 4 в переменной procedureName. Затем, если он найдет «PackageName» в позиции 2, он распечатает сохраненный procedureName и материал из позиции 4. И он использует обратную косую черту как OutputFieldSeperator.

Технически вы можете направить свой grep на это, но awk может просто выполнить сам поиск, вот что я здесь написал.

5

Попробуйте awk:

awk -F'"' 'NR%2{p1=$4;next} {print p1 "/" $4}' 

Тест:

$ awk -F'"' 'NR%2{p1=$4;next} {print p1 "/" $4}' file 
abc/123abc 
bac/bac123 
cde/cd123 
b4u/b4u234 
+0

Это также работает: 'awk -F \" -v OFS =/'{printf "% s% s", $ 4, NR% 2? OFS: ORS}' file' – user000001

+1

@EdMorton, Спасибо. Обновленный ответ – sat

2

Моя первая попытка (и один я на самом деле рекомендую) был таким же, как @ сидел так я удалил его и вот другой подход, если он полезен в каком-то другом контексте:

$ awk -F'"' '{n2v[$2]=$4} !(NR%2){print n2v["ProcedureName"] "/" n2v["PackageName"] }' file 
abc/123abc 
bac/bac123 
cde/cd123 
b4u/b4u234 

n2v означает name2value, имя массива, которое я часто использую для типа приложения, где у нас есть имя для сопоставления значений во входном файле.

2

С GNU Grep и пасты:

grep -oP '"\K[^"]*(?="/)' file | paste -d/- - 

Выход:

 
abc/123abc 
bac/bac123 
cde/cd123 
b4u/b4u234 
+0

Мои мысли в точности, хотя я бы использовал шаблон ''(? <= Value ="). *? (? = ")'' –

+0

@glennjackman: Да, я нашел ваши мысли вчера [ есть] (http://stackoverflow.com/a/32724834/3776858). – Cyrus

0

В качестве альтернативы awk и grep решений.

sed -rn 's|.*"([^"]*)"/>|\1|p' xml | pr -2ats/ 
0

Это может работать для вас (GNU СЭД):

sed 'N;s#.*value="\([^"]*\)".*value="\([^"]*\)".*#\1/\2#' file 

прочитанной две строки в то время, и извлекать значения между двойными кавычками предваряется буквального value=.

Еще немного короче вариант с использованием обратной ссылки на LHS и -r вариант, чтобы сделать регулярное выражение легче читать:

sed -r 'N;s#.*(value=")([^"]*)".*\1([^"]*)".*#\2/\3#' file 

Еще один способ, с помощью удержания пространства и замену:

sed -r 's/.*"(.*)".*/\1/;h;N;s//\1/;H;g;s#\n#/#' file 

Извлекает последнее значение между двойными кавычками в двух последовательных строках и реорганизует результаты в нужную строку.