次のように、行ごとに7つの数字を持つCSVファイルがあります。
1083,20,28,42,23,10,43
1084,20,5,29,59,40,33
1085,39,50,21,12,40,55
1086,45,4,6,23,10,2
1087,36,46,28,32,3,20
最初の数字(列1)を維持し、ファイルが次のように見えるように列2から7まで並べ替えたいと思います。
1083,10,20,23,28,42,43
1084,5,20,29,33,40,59
1085,12,21,39,40,50,55
1086,2,4,6,10,45,23
1087,3,20,28,32,36,46
awk
どうすればこれを行うことができますかsed
?
ありがとう
答え1
そしてperl
:
perl -F, -lape '$_ = join ",", shift @F, sort {$a <=> $b} @F' < input.csv
GNUの使用awk
:
gawk -F, '
{
split($0, a)
printf "%s", a[1]
delete a[1]
n = asort(a)
for (i = 1; i <= n ; i++) printf "%s", FS a[i]
print ""
}' < input.csv
またはjoin.awk
図書館を利用してください(@WeijunZhouに感謝します)
gawk -i join -F, -v OFS=, '
{
split($0, a)
first = a[1]
delete a[1]
n = asort(a)
print first, join(a, 1, n, OFS)
}'
答え2
直面する問題は、ファイルにMAC行末(\ r)があるのに対して、実行中のコマンドはUnix行末(\ n)を想定していることです。
使用Perl
:
$ perl -l015 -F, -0015 -pae '$_ = join ",", shift @F, sort { $a <=> $b } @F' input.csv
オプション:
-l
ORS
=8進数15に設定します\r
。-0
RS
=8進数15に設定します\r
。-p
レコードごとにcsvファイルを繰り返します。 RSは、オプションで\r
設定されているように入力ファイルのレコードを分割します-0
。-F
各レコードを読み取ると、フィールド区切り文字がコンマに設定されます。-a
各レコードはフィールドとして読み取られ、配列に保存されると分割されます@F
。- 注:オプションが提供される順序は重要です。
したがって、取得できる出力にはMACラインエンドも必要です。これが予想される出力が表示されない理由です。代わりに、ここで提供されているすべてのソリューションに応じて、すべての出力レコードが1行に圧縮されます。
答え3
単純化のためにcsv
引用せずに、次のことを試してください。
while IFS= read -r l; do
col1=$(printf '%s' "$l" | cut -d, -f1)
printf '%s,' "$col1"
printf '%s' "$l" | cut -d, -f2- | grep -o "[0-9]*" | sort -n | paste -sd,
done < file
答え4
次のawkメソッドとsedメソッドの組み合わせを試してください。
j=awk '{print NR}' filename | sort -nr| sed -n '1p'
for ((i=1;i<=$j;i++)); do k=`awk -F "," -v i="$i" 'NR==i {print $1}' i.txt` ;echo $k;awk -F "," -v i="$i" 'NR==i {$1=" ";print $0}' i.txt| sed -r "s/^\s+//g"| perl -pne "s/ /\n/g"| sort -n| perl -pne "s/\n/ /g";echo " "| sed "s/.*/&\n/g";done|sed '/^$/d'| sed "N;s/\n/ /g"| sed "s/ /,/g"| sed "s/\,*$//g"
出力
1083,10,20,23,28,42,43
1084,5,20,29,33,40,59
1085,12,21,39,40,50,55
1086,2,4,6,10,23,45
1087,3,20,28,32,36,46