簡體   English   中英

如何使用不同的字段分隔符對多個字段進行排序

[英]How to sort on Multiple Fields with different field separator

我想對多個字段和多個字段分隔符上的文件進行排序。 請幫忙。 這是我的示例數據文件:

$ cat Data3
My Text|50002/100/43
My Message|50001/100/7
Help Text|50001/100/7
Help Message|50002/100/11
Text Message|50001/100/63
Visible Text|50001/100/52
Invisible Text|50002/100/1

第一個字段分隔符是管道符號,第二個字段分隔符是/ 我想首先在第二個字段上對這些數據進行排序,然后在其中將數據按最后一個字段的排序順序(用/分隔)。 最后,我的排序數據應如下所示:

Help Text|50001/100/7
My Message|50001/100/7
Visible Text|50001/100/52
Text Message|50001/100/63
Invisible Text|50002/100/1
Help Message|50002/100/11
My Text|50002/100/43

通過使用sort -k2,2n -t'|' ,我可以對字段2( 50001/50002 )進行排序,但是在該值內,如何對最后一個字段(由/分隔)進行排序?

此數據集的最簡單技巧是將第二列視為版本號。

$ cat Data3 | sort -k2,2V -t'|'
Help Text|50001/100/7
My Message|50001/100/7
Visible Text|50001/100/52
Text Message|50001/100/63
Invisible Text|50002/100/1
Help Message|50002/100/11
My Text|50002/100/43

但是,根據您的輸入,這並不總是有效。 這將起作用,因為第二列中的值相同。

您可以執行fedorqui的建議並運行兩次排序,第二次進行穩定排序。 在聯機幫助頁中:-s,--stable(通過禁用最后查詢比較來穩定排序)

首先對次要排序標准進行排序。 然后執行穩定的排序,這將使排序順序保持在與主要排序條件共享相同鍵的行中。

$ cat Data3 | sort -k3,3n -t'/' | sort -k2,2n -t'|' -s
Help Text|50001/100/7
My Message|50001/100/7
Visible Text|50001/100/52
Text Message|50001/100/63
Invisible Text|50002/100/1
Help Message|50002/100/11
My Text|50002/100/43

在這種情況下,您很幸運,因為-k2,2n -t'|' 會將第二列“ 50001/100/7”視為一個數字,可能是50001。如果將逗號分隔而不是斜杠並且在環境中使用了不同的語言環境,則可能會遇到奇怪的情況。 例如,在我的環境中,默認情況下,我運行en_US.UTF-8,其行為如下。

$ cat Data3 | tr '/' ',' | sort -k3,3n -t',' | LC_NUMERIC=en_US.UTF-8 sort -k2,2n -t'|' -s
Help Text|50001,100,7
My Message|50001,100,7
Invisible Text|50002,100,1
Visible Text|50001,100,52
Text Message|50001,100,63
Help Message|50002,100,11
My Text|50002,100,43

您所期望的是:

$ cat Data3 | tr '/' ',' | sort -k3,3n -t',' | LC_NUMERIC=C sort -k2,2n -t'|' -s
Help Text|50001,100,7
My Message|50001,100,7
Visible Text|50001,100,52
Text Message|50001,100,63
Invisible Text|50002,100,1
Help Message|50002,100,11
My Text|50002,100,43

只要沒有其他'|' ,以下代碼對我'|' 文字中的字符。

tr '|' '/' | sort -n -t '/' -k3 -k4 | sed -re 's/^([^/]*)\\/(.*)$/\\1|\\2/'

awk一個小技巧

$ cat Data3  | awk -F'[|/]' '{print $2"\t"$4"\t"$0}' | sort -k1 -k2 -n | cut -f3-
Help Text|50001/100/7
My Message|50001/100/7
Visible Text|50001/100/52
Text Message|50001/100/63
Invisible Text|50002/100/1
Help Message|50002/100/11
My Text|50002/100/43
  • 您可以-F'[|/]'指定了所有分隔符-F'[|/]'使用awk ,先打印排序鍵$2"\\t"$4 ,然后打印輸入行$0
  • 然后使用多個鍵-k1 -k2進行一種sort (注意:與-k1,2
  • 然后cut回輸入線

在許多情況下通用

您可以使用以下(無效但簡單)的腳本:

#!/usr/bin/perl
print sort  {   @ka = split ?[|/]?, $a;
                @kb = split ?[|/]?, $b;
                $ka[1] <=> $kb[1]
             || $ka[3] <=> $kb[3]
             || $ka[0] cmp $kb[0]
            } <>

您可以省略|| $ka[0] cmp $kb[0] || $ka[0] cmp $kb[0]如果您不希望將具有相同值的行按文本消息排序。

暫無
暫無

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

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