最初の2列の最大値に基づいてソート

最初の2列の最大値に基づいてソート

以下を含むファイルがあります。

1 1 1 1 text1
7 9 4 2 text2
2 2 0.5 0.7 text3
5 4 1 2 text4

最大値に基づいて最初の2つの列をソート(ターミナルに出力)したいと思います。

予想出力:

1 1 1 1 text1
2 1 0.5 0.7 text3
5 4 1 2 text4
7 9 4 2 text2

これはどのように達成できますか?ありがとうございます!

答え1

入力ファイルは次のとおりです。

1 1 1 1 text1
7 9 4 2 text2
2 2 0.5 0.7 text3
5 4 1 2 text4

この入力を使用すると、簡単なsort操作が実行されます。

$ sort << EOF
> 1 1 1 1 text1
> 7 9 4 2 text2
> 2 2 0.5 0.7 text3
> 5 4 1 2 text4
> EOF
1 1 1 1 text1
2 2 0.5 0.7 text3
5 4 1 2 text4
7 9 4 2 text2

入力を次のように変更すると...

$ cat test.txt
1 3 1 1 text1
7 9 4 2 text2
2 1 0.5 0.7 text3
5 4 1 2 text4

これによりタイピングが難しくなります。簡単な方法はsortもう機能しません。他の方法をテストできます。

$ sort -k1,1n -k2,2n < test.txt
1 3 1 1 text1
2 1 0.5 0.7 text3
5 4 1 2 text4
7 9 4 2 text2

これいいえ私たちが期待するもの - 出力の最初の2行が反転されます。行1の最も高い1/2列の値は「3」であり、行2の最も高い1/2列の値は「2」である。

以下は、少なくとも変更された入力ファイルではうまくいくようですが、それは見た目には良くありません(私のawk-fuは弱いです)。

$ awk '{ sorton=$1; if ($2>$1) { sorton=$2 }; print $1, $2, $3, $4, $5, sorton }' < test.txt | sort -k 6 | cut -d " " -f 1-5
2 1 0.5 0.7 text3
1 3 1 1 text1
5 4 1 2 text4
7 9 4 2 text2

@Nominal-Animalと@JJoaoが提案した改善の結果は次のとおりです。

$ awk '{ k= $1>$2 ? $1: $2 ; print k, $0 }' test.txt | sort -g | cut -d ' ' -f 2-
2 1 0.5 0.7 text3
1 3 1 1 text1
5 4 1 2 text4
7 9 4 2 text2

awk(ソリューションを改善するには、この投稿を自由に編集してください。)

答え2

最初の2列の数字を並べ替えるには

sort -n -t " " -k1,1 -k2,2 /path/to/file

答え3

GNUを使用してこれを行うことができますsort

sort -k1,1n -k2,2n yourfile
  • -k列を指定するために使用されます。

答え4

もしawkとしてGNU awk(gawk)があり、そのasort()機能を使用してawk自体内ですべての操作を実行できます。

{
  max = $1 > $2 ? $1 : $2;
  if (max in lines)
    lines[max] = lines[max] ORS $0
  else
    lines[max] = $0
}

END {
  asort(lines, lines, "@ind_num_asc")
  for(i=1; i<=length(lines); i++) { print lines[i] }
}

関連情報