web-dev-qa-db-ja.com

端末から行ごとに並べ替える方法

この質問 を見ていましたが、端末から次のことができるかどうか疑問に思いました。私はPythonでそれをしましたが、それが端末、bashスクリプトなどで実行できるかどうかを確認したいだけです。

次のようなファイルがあるとします。

2,4,5,14,9
40,3,5,10,1

行(行)ごとにソートできますか

2,4,5,9,14
1,3,5,10,40

それとも複雑すぎますか?私はpythonを使用してそれをやった、それができるかどうかを知りたいので、次回pythonを使用しないかもしれません。私がやったことは、リストを作成して並べ替えることです。

7
Lynob

別のPerlアプローチを次に示します。

Perl -F, -lane 'print join ",",sort {$a<=>$b} @F' file.txt

そして、別のシェル/コアユーティリティ(個人的には、同じ考えを使用するsteeldriverの 優秀な答え が好きです):

while read line; do 
    tr , $'\n' < <(printf -- "%s" "$line") | sort -g | tr $'\n' , | sed 's/,$/\n/';
done < file.txt
5
terdon

これはあなたが探しているものについて行うべきです。ファイル(test.txt)を読み取り、元のファイルに表示されるのと同じ順序でソートされた行を含む出力ファイル(sorted.txt)を作成します。

while read line; do j=$(echo "$line" | sed -e 's/,/\n/g' | sort -n); echo "$j" 
    | sed -e 's/ /,/g' >> sorted.txt; done < test.txt
7
jkt123

ここにawkソリューションがあります。

while read -r line; do (echo $line | awk '{ n=split($1,a,","); asort(a); for(i=0;i<=n;i++) { print a[i];}}') | xargs | sed -e 's/ /,/g'; done < text.txt

説明:

  • awk '{ n=split($1,a,","); asort(a); for(i=0;i<=n;i++) { print a[i];}}'

    awk区切り文字,に従ってフィールド1を分割し、各値を配列aに格納します。最後に、最上位が変数nに格納されます。次のasort(a)関数は、配列値をソートします。次に、awkコマンド内のforループは、ソートされた値をレコードごとの形式で出力します。

  • xargs | sed -e 's/ /,/g'

    xargsは、すべての行を単一の行に結合します。

  • sed -e 's/ /,/g'

    スペースをコンマ,に置き換えます

  • while read -r line;

    上記のawkxargssed関数はすべて、whileループの助けを借りて1行ずつ実行されます。

4
Avinash Raj

コマンドラインスクリプティングを使用してやりたいことを行う際の唯一の本当の困難は、利用可能なsort関数がファイル内の行をソートすることを期待していることです行内のフィールドではなく。これを回避するには、フィールド区切り文字を行ごとにsort関数の前の改行で置き換え、ソート後に各行で改行を区切り文字で再度置き換えます。

それを可能にする多くの利用可能なテキスト処理ユーティリティがあります(sedawk、または単純なtrを含みます) 。入力をコンマ区切りにすることを想定していると仮定すると(例ではコンマと空白区切り文字が混在している)、次のようにできます。

while read line; do 
  sorted=$(sort -g -- <<< "${line//,/$'\n'}")
  printf -- "${sorted//$'\n'/,}\n"
done < file

入力でスペース区切り文字を処理する必要がある場合doは、入力サブストリングの文字リスト[, ]の一部としてそれらを追加できます。置換:

while read line; do 
  sorted=$(sort -g -- <<< "${line//[, ]/$'\n'}")
  printf -- "${sorted//$'\n'/,}\n"
done < file

(ただし、出力は厳密にコンマ区切りのままであることに注意してください)。

4
steeldriver

Trとsedを使用する

精神的には jkt123が書いたもの に似ています:

while read i; do tr , \\n <<< $i | sort -n | tr \\n , | sed 's/,$//'; done

行を反復処理し、各行でコンマを改行で置き換え、結果の行を数値的に並べ替えてから、改行をコンマに戻します。主な問題は、これが改行ではなくコンマで結果全体を終了することです。これは、その最後のsedによって対処されます。最後のコンマを削除し、暗黙的に出力に改行を追加します。

Bash配列を使用する

この「カンマで結合」の問題に対処する別のアプローチを次に示します。

while read i; do j=( $(tr , \\n <<< $i | sort -n) ); ( IFS=,; echo "${j[*]}"; ); done

または、行の折り返しを使用して記述します。

while read i
do
   j=( $(tr , \\n <<< $i | sort -n) )
   ( IFS=,; echo "${j[*]}"; )
done

Bash配列を使用してソートされた行の結果を保存し、bashがIFS特殊変数を使用して配列を文字列リテラルに展開する方法を利用します。

3
MvG

python -c "your code here" input.txt

または、プログラムに複数の行があり、eval()が遅すぎる場合:

python yourprogram.py input.txt

このonelinerは動作します:

python -c "for l in open('input.txt'):print(','.join(sorted(l.strip().split(','), key=int)))"
3
Cees Timmerman

の 最短 Perl onelinerを使用したソリューション:

Perl -ne 'print join(",", sort { $a <=> $b } split(/,|\n/))."\n"' text.txt
2
Sylvain Pineau

Perlを使用して簡単にこれを行うことができます

ファイルtext.txtがあると考えてください

cat text.txt

1,5,7,8,3,6
10,34,67,1,2,0,5

これで、次のPerlコードはtext.txtの行をソートします

 Perl -i -e 'while(<>){chomp; my @sorted = sort { $a <=> $b } split(",", $_); print join (",", @sorted); print "\n"}' text.txt

ソート後

cat text.txt

1,3,5,6,7,8
0,1,2,5,10,34,67
2
Stormvirux

私もこの機能を必要としていましたが、解決策は次のとおりです(データがテストファイルにあると仮定)。

cat test | while read line; do echo $(echo $line | datamash -t',' transpose |sort -g| datamash -t',' transpose); done
1
Eissa N.