この質問 を見ていましたが、端末から次のことができるかどうか疑問に思いました。私はPythonでそれをしましたが、それが端末、bashスクリプトなどで実行できるかどうかを確認したいだけです。
次のようなファイルがあるとします。
2,4,5,14,9
40,3,5,10,1
行(行)ごとにソートできますか
2,4,5,9,14
1,3,5,10,40
それとも複雑すぎますか?私はpythonを使用してそれをやった、それができるかどうかを知りたいので、次回pythonを使用しないかもしれません。私がやったことは、リストを作成して並べ替えることです。
別の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
これはあなたが探しているものについて行うべきです。ファイル(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
ここに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;
上記のawk
、xargs
、sed
関数はすべて、while
ループの助けを借りて1行ずつ実行されます。
コマンドラインスクリプティングを使用してやりたいことを行う際の唯一の本当の困難は、利用可能なsort
関数がファイル内の行をソートすることを期待していることです行内のフィールドではなく。これを回避するには、フィールド区切り文字を行ごとにsort
関数の前の改行で置き換え、ソート後に各行で改行を区切り文字で再度置き換えます。
それを可能にする多くの利用可能なテキスト処理ユーティリティがあります(sed
、awk
、または単純な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
(ただし、出力は厳密にコンマ区切りのままであることに注意してください)。
精神的には jkt123が書いたもの に似ています:
while read i; do tr , \\n <<< $i | sort -n | tr \\n , | sed 's/,$//'; done
行を反復処理し、各行でコンマを改行で置き換え、結果の行を数値的に並べ替えてから、改行をコンマに戻します。主な問題は、これが改行ではなくコンマで結果全体を終了することです。これは、その最後のsedによって対処されます。最後のコンマを削除し、暗黙的に出力に改行を追加します。
この「カンマで結合」の問題に対処する別のアプローチを次に示します。
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
特殊変数を使用して配列を文字列リテラルに展開する方法を利用します。
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)))"
の 最短 Perl onelinerを使用したソリューション:
Perl -ne 'print join(",", sort { $a <=> $b } split(/,|\n/))."\n"' text.txt
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
私もこの機能を必要としていましたが、解決策は次のとおりです(データがテストファイルにあると仮定)。
cat test | while read line; do echo $(echo $line | datamash -t',' transpose |sort -g| datamash -t',' transpose); done