我有一个金发碧眼的时刻,似乎无法理解它,但我有一个csv文件(下面的示例),其中我想按第一个值排序行在行中 - 六 - 数字(从小到大)
570e2e5c,1460539517,SOM3-String-123,08-5a-0c-59
570e2e81,1460539520,SOM3-String-123,08-00-0c-59
570e2e87,1460539521,SOM3-String-123,09-5e-6b-22
570e2e5e,1460539518,SOM3-String-123,08-00-0c-59
570e2e90,1460539522,SOM3-String-123,08-00-0c-59
570e2e95,1460539523,SOM3-String-123,09-00-67-22
570e2e60,1460539519,SOM3-String-123,09-00-68-22
问:如何用BASH脚本按行十六进制的第一行元素排序csv文件行?
附录:
所以我使用以下代码将十六进制字符串转换为dec字符串:
IFS=','
while read f1 f2 f3 f4
do
f1_upper_case=`echo "$f1" | tr '[:lower:]' '[:upper:]'`
f1_dec=$((16#$f1_upper_case))
echo "$f1_dec,$f2,$f3,$f4" >>$csv_temp
done < $csv
我将尝试在csv文件中按$f1_dec
排序。
答案 0 :(得分:2)
如果字符串都具有相同的数字位数,则可以按词法排序。如果您可能有一些不同的大小数字,那么您最好的选择可能是转换为十进制,数字排序,然后转换回来:
awk -F, -vOFS=, '{$1=strtonum("0x"$1)}1' $filename | sort -t, -n -k1,1 |
awk -F, -vOFS=, '{$1=sprintf("%x",$1)}1' >$new_filename
运行您的示例输入,我得到此输出:
570e2e5c,1460539517,SOM3-String-123,08-5a-0c-59
570e2e5e,1460539518,SOM3-String-123,08-00-0c-59
570e2e60,1460539519,SOM3-String-123,09-00-68-22
570e2e81,1460539520,SOM3-String-123,08-00-0c-59
570e2e87,1460539521,SOM3-String-123,09-5e-6b-22
570e2e90,1460539522,SOM3-String-123,08-00-0c-59
570e2e95,1460539523,SOM3-String-123,09-00-67-22
说明:
-F,
告诉awk
在逗号的(F)字段分隔符上拆分输入行。 -vOFS=,
告诉它使用逗号作为(O)utput(F)ield(S)eparator - 也就是说,当它将行打印出来时,将逗号保留为分隔符。
字符串中的代码每行输入运行一次,字段分为变量$1
,$2
等。{
内的块... {首先运行{1}}并更改}
的值;之后的$1
会导致新的1
字段打印出来。
$1
函数将字符串转换为数字,遵守C字面约定,前导0表示基数为8,前导0x表示基数为16.所以通过将strtonum
添加到"0x"
,我们得到一个它将识别为十六进制的字符串。我们在$1
中返回并存储的号码将在打印出来时自动转换为小数。
因此,第一个$1
命令的最终结果是将第一列转换为十进制。然后我们可以awk
。我们再次使用逗号作为字段分隔符 - 对于sort
,我们使用sort
表示。我们希望以数字方式排序(-t
),并且我们希望排序键(-n
)仅包含第一个字段(-k
)。
然后我们要转换回十六进制。第二个1,1
与第一个awk
大致相同,但我们称之为strtonum
,而不是sprintf
。这是一个从其他值构建字符串的函数,"%x"
格式说明符表示取一个数字并将其转换为十六进制字符串。
答案 1 :(得分:0)
输入:
$ cat /tmp/so36636125.txt
570e2e5c,1460539517,SOM3-String-123,08-5a-0c-59
570e2e81,1460539520,SOM3-String-123,08-00-0c-59
570e2e87,1460539521,SOM3-String-123,09-5e-6b-22
570e2e5e,1460539518,SOM3-String-123,08-00-0c-59
570e2e90,1460539522,SOM3-String-123,08-00-0c-59
570e2e95,1460539523,SOM3-String-123,09-00-67-22
570e2e60,1460539519,SOM3-String-123,09-00-68-22
转换一个班轮:
$ awk '{ dec = sprintf("%d", "0x" $1); print dec " " $0 }' /tmp/so36636125.txt | sort -n -k 1 | cut -f2- -d' '
570e2e5c,1460539517,SOM3-String-123,08-5a-0c-59
570e2e5e,1460539518,SOM3-String-123,08-00-0c-59
570e2e60,1460539519,SOM3-String-123,09-00-68-22
570e2e81,1460539520,SOM3-String-123,08-00-0c-59
570e2e87,1460539521,SOM3-String-123,09-5e-6b-22
570e2e90,1460539522,SOM3-String-123,08-00-0c-59
570e2e95,1460539523,SOM3-String-123,09-00-67-22
$ awk --version
GNU Awk 3.1.7
说明:
awk
添加一个新的第一列作为。的十进制表示
十六进制数sort
数字化第一栏cut
删除第一个
柱