[英]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.