簡體   English   中英

Bash:讀取 CSV 文件並根據條件對列進行排序

[英]Bash: Reading a CSV file and sorting column based on a condition

我正在嘗試讀取 CSV 文本文件並根據條件打印一列(已排序)的所有條目。

輸入樣本如下:

Computer ID,User ID,M
Computer1,User3,5
Computer2,User5,8
computer3,User4,9
computer4,User10,3
computer5,User9,0
computer6,User1,11

如果小時數(第三列)大於零,則需要打印用戶 ID(第二列)。 但是,打印的數據應根據用戶 ID 進行排序。

我編寫了以下腳本:

while IFS=, read -r col1 col2 col3 col4 col5 col6 col7 || [[ -n $col1 ]]
do
    if [ $col3 -gt 0 ] 
    then
        echo "$col2" > login.txt
    fi
done < <(tail -n+2 user-list.txt)

這個腳本的輸出是:

User3
User5
User4
User10
User1

我期待以下輸出:

User1
User3
User4
User5
User10

任何幫助,將不勝感激。 TIA

awk -F, 'NR == 1 { next } $3 > 0 { match($2,/[[:digit:]]+/);map[$2]=substr($2,RSTART) } END { PROCINFO["sorted_in"]="@val_num_asc";for (i in map) { print i } }' user-list.txt > login.txt

用-F設置字段分隔符為逗號,忽略頭用NR == 1 { next }當第3個分隔字段大於0時設置數組(映射)的索引給用戶。值設置數字部分User 字段的(通過 match 函數找到) 在 end 塊中,將排序順序設置為值、數字、升序並循環遍歷創建的地圖數組。

您的腳本的問題(我認為“排序不起作用”)是您重定向(並且可能試圖排序)的地方 - 您自己的腳本的以下變體可以完成這項工作:

#!/bin/bash
while IFS=, read -r col1 col2 col3 col4 col5 col6 col7 || [[ -n $col1 ]]
do
    if [ $col3 -gt 0 ] 
    then
        echo "$col2"
    fi
done < <(tail -n+2 user-list.txt) | sort > login.txt

編輯 1:匹配新要求

當然我們可以修復排序; sort -k1.5,1.7n > login.txt

當然,這也只有在您的用戶 ID 都是 4 個字母和 n 個數字時才有效......

按 ASCII 順序排序:

tail -n +2 user-list.txt | perl -F',' -lane 'print if $F[2] > 0;' | sort -t, -k2,2 
computer6,User1,11
computer4,User10,3
Computer1,User3,5
computer3,User4,9
Computer2,User5,8

或按用戶編號按數字排序:

tail -n +2 user-list.txt | perl -F',' -lane 'print if $F[2] > 0;' | sort -t, -k2,2V
computer6,User1,11
Computer1,User3,5
computer3,User4,9
Computer2,User5,8
computer4,User10,3

使用 awk 進行條件處理和sort進行排序:

$ awk -F, '                       # comma delimiter
FNR>1 && $3 {                     # skip header and accept only non-zero hours
    a[$2]++                       # count instances for duplicates
}
END {
    for(i in a)                   # all stored usernames
        for(j=1;j<=a[i];j++)      # remove this if there are no duplicates
            print i | "sort -V"   # send output to sort -V
}' file

輸出:

User1
User3
User4
User5
User10

如果沒有重復的用戶名,可以更換a[$2]++只有a[$2]和刪除后面for 此外,實際上不需要在 awk 程序中進行sort ,您也可以將數據從 awk 管道傳輸到sort ,例如:

$ awk -F, 'FNR>1&&$3{a[$2]++}END{for(i in a)print i}' file | sort -V 

FNR>1 && $3跳過標題並處理小時列不為空的記錄。 如果您的數據有負小時數的記錄,而您只想要正小時數,請將其更改為FNR>1 && $3>0

或者您可以將grep與 PCRE 一起使用並sort

$ grep -Po "(?<=,).*(?=,[1-9])" file | sort -V

暫無
暫無

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

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