2012-05-26 3 views
0

Как отсортировать массив «python dictionary-style» e.g. ("A: 2" "B: 3" "C: 1") в bash по значению? Я думаю, этот фрагмент кода сделает его более ясным в моем вопросе.сортировка массива «ключ/значение» в bash

State="Total 4 0 1 1 2 0 0" 
W=$(echo $State | awk '{print $3}') 
C=$(echo $State | awk '{print $4}') 
U=$(echo $State | awk '{print $5}') 
M=$(echo $State | awk '{print $6}') 
WCUM=("Owner: $W;" "Claimed: $C;" "Unclaimed: $U;" "Matched: $M") 
echo ${WCUM[@]} 

Это будет просто напечатать массив: Owner: 0; Claimed: 1; Unclaimed: 1; Matched: 2

Как отсортировать массив (или выход), устраняя любую пару с значением «0», так что результат, как это:

Matched: 2; Claimed: 1; Unclaimed: 1 

Заранее благодарим за любую помощь или предложения. Ура !!

+0

Что вы сортируете, «Совмещено»? – John3136

+1

Использовать python было бы моим советом! ИМХО, ты оставил сладкое пятно баха. –

+0

@ NickCraig-Wood: Очевидно, вы не знаете bash. –

ответ

2

Быстрая и грязная идея будет (это просто сортирует вывод, а не массив):

echo ${WCUM[@]} | sed -e 's/; /;\n/g' | awk -F: '!/ 0;?/ {print $0}' | sort -t: -k 2 -r | xargs 
+0

Спасибо Michał, это сработало отлично. Сортировка массива или вывода - в любом случае для меня работает. Все, что мне нужно, чтобы напечатать отформатированный результат. Ура !! – MacUsers

0

Еще одна попытка, используя некоторые особенности Баш, но все еще нуждается рода, что имеет решающее значение:

#! /bin/bash 
State="Total 4 1 0 4 2 0 0" 
string=$State 
for i in 1 2 ; do  # remove unnecessary fields 
    string=${string#* } 
    string=${string% *} 
done 

# Insert labels 
string=Owner:${string/ /;Claimed:} 
string=${string/ /;Unclaimed:} 
string=${string/ /;Matched:} 

# Remove zeros 
string=(${string[@]//;/; }) 
string=(${string[@]/*:0;/}) 
string=${string[@]} 

# Format 
string=${string//;/$'\n'} 
string=${string//:/: } 

# Sort 
string=$(sort -t: -nk2 <<< "$string") 
string=${string//$'\n'/;} 
echo "$string" 
1
echo -e ${WCUM[@]} | tr ';' '\n' | sort -r -k2 | egrep -v ": 0$" 

Сортировка и фильтрация являются самостоятельные шаги, так что если вы только хотели, чтобы отфильтровать значения 0, было бы намного проще.

Append в

| tr '\n' ';' 

, чтобы получить его к одной линии снова в конце концов.

nonull=$(for n in ${!WCUM[@]}; do echo ${WCUM[n]} | egrep -v ": 0;"; done | tr -d "\n") 

Я не вижу хороший повод, чтобы положить конец $ W $ C $ U точкой с запятой, а $ M нет, поэтому вместо того, чтобы адаптировать свой код к этому различию, я бы устранить этот особый случай. Если это невозможно, я бы добавил точку с запятой временную до $ M и удалил ее в конце.

+0

согласился на предмет «с запятой»; это была первая версия, и я все еще решал, что делать. Спасибо за код - у меня действительно есть идея использовать это в другом месте. Только одно: часть 'seq' может быть сокращена следующим образом:' $ {! WCUM [@]} '. Ура !! – MacUsers

+0

@MacUsers: Хорошая идея - сделано. –

Смежные вопросы