[bash] sorteren meerdere kolommen met een twist

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MisterE
  • Registratie: April 2002
  • Laatst online: 24-08 22:07
Ik heb per regel 3 getallen. Elk getal heeft evenveel "waarde".
Maw, als het derde getal "100" is is deze hoger dan getal "99" in het middelste veld.

Dus de output zou als volgt moeten worden:

000-000-100
000-099-000
070-000-003
070-000-002

Volgens mij kan dit niet met "sort". Iemand een idee hoe dit te realiseren?

Acties:
  • 0 Henk 'm!

  • RemcoDelft
  • Registratie: April 2002
  • Laatst online: 03-05 10:30
Een klein scriptje maken? Per regel het hoogste getal bepalen, en dan sorteren?

Wat doe je als er 2 regels met 099 zijn? En als er slechts 3 cijfers per getal zijn is het zelfs handmatig zo te doen.

Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 15:47
Als ik het goed begrijp, ziet de invoer er net zo uit als die voorbeelduitvoer (met mogelijk de regels in een andere volgorde). En ik neem aan dat niet alleen het hoogste getal telt, maar mogelijk ook de andere getallen, zoals bij de laatste twee regels die beide 070 als hoogste getal hebben (en dan wint 003 van 002).

Je wilt dus eigenlijk eerst per regel de drie getallen sorteren en vervolgens alle regels sorteren. Maar in de uitvoer moeten de drie getallen per regel in de oorspronkelijke volgorde blijven staan? Dat lijkt me niet bepaald leuk met alleen bash en coreutils zoals sort. Met bijv. Python is het vrij simpel:
Python:
1
2
3
4
5
from sys import stdin, stdout

sorted_numbers = lambda line: sorted(line.split('-'), reverse=True)

stdout.writelines(sorted(stdin, key=sorted_numbers, reverse=True))

Acties:
  • 0 Henk 'm!

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 15:07

Super_ik

haklust!

Ook niet met sort -v ? (Of was het nou -V, iig, versie sort)

/edit:
-V of --version-sort dus

[ Voor 23% gewijzigd door Super_ik op 19-05-2015 22:00 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


Acties:
  • 0 Henk 'm!

  • MisterE
  • Registratie: April 2002
  • Laatst online: 24-08 22:07
ik had de hoop op een "one-liner", nu een script gemaakt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
is_higher () {
  string1="$1"
  string2="$2"
  
  s1f1=$(echo "$string1" | cut -d"-" -f1)
  s1f2=$(echo "$string1" | cut -d"-" -f2)
  s1f3=$(echo "$string1" | cut -d"-" -f3)
  
  s2f1=$(echo "$string2" | cut -d"-" -f1)
  s2f2=$(echo "$string2" | cut -d"-" -f2)
  s2f3=$(echo "$string2" | cut -d"-" -f3)
  
  array_s1=($s1f1 $s1f2 $s1f3)
  array_s2=($s2f1 $s2f2 $s2f3)
  
  # echo "array_s1 = ${array_s1[@]}"
  # echo "array_s2 = ${array_s2[@]}"
  
  # geen idee waarom "reverse" nodig is
  array_s1_sorted=( $(
    for el1 in "${array_s1[@]}"
    do
      echo "$el1"
    done | sort -nr
  ))
  
  array_s2_sorted=( $(
    for el2 in "${array_s2[@]}"
    do
      echo "$el2"
    done | sort -nr
  ))
  
  #echo "array_s1_sorted = ${array_s1_sorted[@]}"
  #echo "array_s2_sorted = ${array_s2_sorted[@]}"
  
  # dit moet makkelijker kunnen? 
  array_s1_sorted_string=$(echo ${array_s1_sorted[@]} | tr " " "|")
  array_s2_sorted_string=$(echo ${array_s2_sorted[@]} | tr " " "|")
  
  #echo "array_s1_sorted_string = $array_s1_sorted_string"
  #echo "array_s2_sorted_string = $array_s2_sorted_string"
  
  array_both=($array_s1_sorted_string $array_s2_sorted_string)

  array_both_sorted=( $(
    for elb in "${array_both[@]}"
    do
      echo "$elb"
    done | sort -nr
  ))
  
  
  if [ ${array_both_sorted[0]} = "$array_s1_sorted_string" ]; then
    echo "parameter 1 is hoger"
    return 1
  else
    echo "parameter 2 is hoger"
    return 0
  fi
}


#is_higher "70-00-03" "70-00-04"
#is_higher "70-00-04" "70-00-03"

#is_higher "7-00-00" "60-00-00"
#is_higher "60-00-00" "7-00-00"

#is_higher "60-00-00" "0-0-1000"
#is_higher "0-0-1000" "60-00-00"

#is_higher "5-00-80" "00-90-4"


exchange()
{
  temp="${ARRAY[$1]}"
  ARRAY[$1]="${ARRAY[$2]}"
  ARRAY[$2]="$temp"
}


# based on: http://www.bashguru.com/2010/07/bubble-sort-shell-script.html
sortnumbers()
{
  for (( last=count-1;last>0;last--))
  do
    #echo "outer loop: last = $last"

    for((i=0;i<last;i++))
    do
      j=$((i+1))
      #echo "inner loop: i = $i"
      #echo "array i: ${ARRAY[i]}"
      #echo "array j: ${ARRAY[j]}"

      is_higher "${ARRAY[i]}" "${ARRAY[j]}"
      retval=$?

      if [ $retval -eq 1 ]; then
    #echo "swap"
    exchange "$i" "$j"
    #echo "array is nu: ${ARRAY[@]}"
      fi
    done
  done
}


index=0
while read line; do
  #echo "line: $line"
  ARRAY[$index]="$line"
  ((index++))
done < "numbers.txt"

count=${#ARRAY[@]}
echo $count
echo ${ARRAY[@]} 
sortnumbers
echo ${ARRAY[@]}


De performance is echter buitengewoon slecht. Hij moet ook voor elke vergelijking de string uit elkaar trekken, sorten en vergelijken.
Ik denk dat ik het naar een echte taal ga omzetten met structs/objecten.

iig, bedankt voor de moeite

Acties:
  • 0 Henk 'm!

  • RemcoDelft
  • Registratie: April 2002
  • Laatst online: 03-05 10:30
Je hebt mijn vragen nog niet beantwoord... Een eenvoudige manier zou zijn het hoogste getal aan het begin van elke rij toe te voegen, dan te sorteren, en het eerste getal weer te verwijderen.

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Bash:
1
2
3
4
5
6
7
8
9
10
11
12
while IFS=- read A B C;
do
  if [ "$A" -gt "$B" -a "$A" -gt "$C" ]
  then
    echo "$A" "$A-$B-$C"
  elif [ "$B" -gt "$C" ]
  then
    echo "$B" "$A-$B-$C"
  else
    echo "$C" "$A-$B-$C"
  fi
done <inputfile | sort -g | cut '-d ' -f2 > outputfile

Het kan gerust op 1 lijn...

Krijg ik nu een 10/10 van de leraar?

[ Voor 6% gewijzigd door H!GHGuY op 28-05-2015 19:26 ]

ASSUME makes an ASS out of U and ME

Pagina: 1