2013-02-01 183 views
1

我有這樣一個文件:重新排列列表中BASH

FILE.DAT

1 2 
1 3 
2 1 
2 4 
2 3 
3 4 

左邊一列進行排序。我想編寫一個新的文件liek這樣的:

1 2 3 
2 1 4 3 
3 4 

在第一列應該是FILE.DAT左欄數量和它旁邊的右列數。任何幫助?

回答

3
#!/bin/bash 
awk -f <(cat - <<-'EOF' 
    { 
    b[$1, a[$1]++] = $2; 
    } 
    END { 
    for (i in a) { 
     printf "%d ", i; 
     for (j = 0; j < a[i]; j++) { 
     printf "%d ", b[i, j]; 
     } 
     print "" 
    } 
    } 
EOF 
) < /dev/stdin 

輸出:

$ ./script.sh < file.dat 
1 2 3 
2 1 4 3 
3 4 

該腳本將與awk運行。名稱如果file.awk

{ 
    b[$1, a[$1]++] = $2; 
} 
END { 
    for (i in a) { 
     printf "%d ", i; 
     for (j = 0; j < a[i]; j++) { 
      printf "%d ", b[i, j]; 
     } 
     print "" 
    } 
} 

像這樣運行:

awk -f file.awk < file.dat 
+0

我創造了awk腳本'file.awk'與你的答案,然後做了'chmod + x file.awk'使它變得可以改變。我如何加載'file.dat'數字? –

+0

上面的腳本是一個'bash'腳本。運行它爲'./script.sh user000001

+0

感謝您的編輯 –

2

好您已經在接受的答案。不過,我想爲您的有趣問題添加另一個更簡單(也許)簡短的單行程式。

awk '$1 in a{a[$1]=a[$1]" "$2;next}{a[$1]=$0}END{for(i in a)print a[i]}' file 

看到它與你的代碼工作:

kent$ cat test.txt 
1 2 
1 3 
2 1 
2 4 
2 3 
3 4 

kent$ awk '$1 in a{a[$1]=a[$1]" "$2;next}{a[$1]=$0}END{for(i in a)print a[i]}' test.txt 
1 2 3 
2 1 4 3 
3 4 
0

下面是使用awk一個辦法:

awk '{ a[$1] = (a[$1] ? a[$1] FS : "") $2 } END { for (i in a) print i, a[i] | "sort" }' file 

結果:

1 2 3 
2 1 4 3 
3 4 
3

這些答案並不需要整個文件被存儲 在記憶中。他們都需要對文件進行排序。

AWK:

awk ' 
    $1 != prev { 
     if (NR > 1) print "" 
     printf "%d %d", $1, $2 
     prev=$1 
     next 
    } 
    {printf " %d", $2} 
    END {print ""} 
' file.dat 

相當於bash下

prev="" 
while read a b; do 
    if [[ $prev != $a ]]; then 
     [[ -n $prev ]] && echo 
     printf "%d %d" $a $b 
     prev=$a 
    else 
     printf " %d" $b 
    fi 
done < file.dat 
echo 
2

這也適用

awk '{a[$1]=a[$1]$2" "} END {for (i in a) {print i,a[i]}}' temp.txt

+0

這比六小時前我的回答好嗎?據推測,OP想要排序的輸出。 – Steve

+0

@steve我知道你的解決方案總是比較好,我不認爲我只是根據輸出給出我的答案。 OP沒有提到有問題的排序輸出事物。 – user2134226