
我想根據字母順序更改列資料的順序
輸入
c,a,b
e,k,d
輸出
a,b,c
d,e,k
目前,我正在使用下面的程式碼
awk -F"," -v OFS="," '{
if($1<=$2 && $2<=$3)
{print $1,$2,$3}
else if($1<=$2 && $3<=$2)
{print $1,$3,$2}
else if($2<=$1 && $1<=$3)
{print $2,$1,$3}
else if($2<=$1 && $3<=$1)
{print $2,$3,$1}
else if($3<=$2 && $2<=$1)
{print $3,$2,$1}
else
{print $3,$1,$2}}' test.txt
您能幫我提供一個更簡單的解決方案來處理具有 4 列或更多列的文件嗎
答案1
如果您同意perl
:
$ perl -F, -lane 'print join ",", sort @F' ip.txt
a,b,c
d,e,k
-F,
指定要分割的輸入行,
作為分隔符,結果可透過@F
陣列取得
sort @F
join
將按字母順序排序,結果數組將使用,
分隔符號進行組合
和GNU awk
$ awk 'BEGIN{PROCINFO["sorted_in"] = "@val_str_asc"}
{s = ""; c=0; split($0,a,",");
for(k in a) s = c++ ? s "," a[k] : a[k];
print s}' ip.txt
a,b,c
d,e,k
看gawk 手冊:使用預先定義的陣列掃描順序有關上面使用的數組排序的詳細信息
答案2
使用 GNU awk 進行排序:
$ cat tst.awk
BEGIN {
FS=OFS=","
}
{
sub(/\r$/,"")
print sort($0)
}
function sort(inStr, arr,idx,sep,outStr) {
PROCINFO["sorted_in"] = "@val_str_asc"
split(inStr,arr)
for (idx in arr) {
outStr = outStr sep arr[idx]
sep = OFS
}
return outStr
}
$ awk -f tst.awk file
a,b,c
d,e,k
或使用任何 awk,但執行速度會慢得多,因為它會產生一個 shell 來sort
為每行輸入呼叫 UNIX:
$ cat tst.awk
BEGIN {
FS=OFS=","
}
{
sub(/\r$/,"")
print sort($0)
}
function sort(inStr, cmd,line,sep,outStr) {
gsub(/,/,"\n",inStr)
cmd = "printf \047%s\n\047 \047" inStr "\047 | sort"
while ( (cmd | getline line) > 0 ) {
outStr = outStr sep line
sep = OFS
}
close(cmd)
return outStr
}
$ awk -f tst.awk file
a,b,c
d,e,k
這sub(/\r$/,"")
是因為您發布的範例輸入中有 DOS 行結尾,但發布的預期輸出中沒有。
答案3
perl -nlE 'say join ",", sort split ","' file.txt
解釋:
for each line like "r,d,a":
"r,d,a"
↓ split "," it
("r","d","a")
↓ sort it
("a","d","r")
↓ join "," it
"a,d,r"
say it