簡體   English   中英

Bash 按列對列表進行排序

[英]Bash Sorting a List by Columns

我正在對第 2 列進行反向排序。至於第 1 列,如果多行具有相同的 $2 值,我希望它們以相反的順序排序。 目前,我已將此列表存儲在 bash 腳本中的一個變量中。 有沒有sed或者awk function可以用?

例如,我現在的 output 是:

123, 3
124, 3
12345, 2
898, 1
1010, 1

我想要的是:

124, 3
123, 3
12345, 2
1010, 1
898, 1

這不是一個簡單的awk腳本,但也不難。 您只需使用下面的數組a[]來存儲第二個字段的相等值的第一個字段的值。 如果設置了last (例如,不是第一條記錄)並且第二個字段發生變化,則您 output 當前數組並重置數組(即規則 1)。

在規則 2 中,您只需掃描現有數組並按順序將當前第一個字段插入數組中。 您保留第二個字段的last值,以便知道它何時更改。 您使用END規則來 output 最后一組值,例如

awk -F, '
    last && $2 != last {
        for (i=1; i<=n; i++)
            print a[i]", "last;
        delete a
        n = 0
    }
    {
        swapped=0
        for (i=1; i<=n; i++)
            if ($1 > a[i]) {
                swapped=1
                for (j=n+1; j>i; j--)
                    a[j]=a[j-1]
                a[i]=$1
            }
        if (!swapped)
            a[++n]=$1
        else
            n++
        last=$2
    }
END {
    for (i=1; i<=n; i++)
        print a[i]", "last
    }
' file

swapped標志只是告訴您當前的第一個字段是在現有元素之前插入到數組中( swapped == 1 )還是只是在末尾添加( swapped == 0 )。

示例使用/輸出

使用名為file的文件中的示例文件,您可以簡單地更改為包含它的目錄, select 上面的腳本用鼠標(將文件名更改為您的文件名)然后鼠標中鍵將腳本粘貼到終端中,例如

$ awk -F, '
>     last && $2 != last {
>         for (i=1; i<=n; i++)
>             print a[i]", "last;
>         delete a
>         n = 0
>     }
>     {
>         swapped=0
>         for (i=1; i<=n; i++)
>             if ($1 > a[i]) {
>                 swapped=1
>                 for (j=n+1; j>i; j--)
>                     a[j]=a[j-1]
>                 a[i]=$1
>             }
>         if (!swapped)
>             a[++n]=$1
>         else
>             n++
>         last=$2
>     }
> END {
>     for (i=1; i<=n; i++)
>         print a[i]", "last
>     }
> ' file
124,  3
123,  3
12345,  2
1010,  1
898,  1

檢查一下,如果您有任何問題,請告訴我。

使用 Perl 單行和sort的組合。 一行代碼將,定界符轉換為制表符(並返回)。 sort使用-r選項進行反向排序,使用-g選項進行數字排序。 選項-kN,N指定僅按字段N排序,這里是第 2 個,然后是第 1 個字段。

perl -pe 's/, /\t/' in_file | sort -k2,2gr -k1,1gr | perl -pe 's/\t/, /' > out_file

例如:

創建示例輸入文件:

cat > foo <<EOF
123, 3
124, 3
12345, 2
898, 1
1010, 1
EOF

運行命令:

cat foo | perl -pe 's/, /\t/' | sort -k2,2gr -k1,1gr | perl -pe 's/\t/, /' 

Output:

124, 3
123, 3
12345, 2
1010, 1
898, 1

Perl 一行代碼使用這些命令行標志:
-e :告訴 Perl 查找內聯代碼,而不是在文件中。
-p :一次循環輸入一行,默認情況下將其分配給$_ 在每次循環迭代后添加print $_

也可以看看:
perldoc perlrun :如何執行 Perl 解釋器:命令行開關
perldoc perlrequick : Perl 正則表達式快速入門

還有awk ,你可以試試這個:

awk 'BEGIN{RS=""; OFS=FS="\n"} {tmp2 = $2; $2 = $1; $1 = tmp2; tmp5=$5; $5=$4; $4=tmp5}1' file
124, 3
123, 3
12345, 2
1010, 1
898, 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM