我有一个金发碧眼的时刻,似乎不能让我的头周围,但我有一个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文件的行?
附录:
因此,我用以下代码将十六进制字符串转换为十进制字符串:
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
排序。
2条答案
按热度按时间qvtsj1bj1#
如果字符串的位数和字母大小写都相同,就像示例数据中的情况一样,则可以按原样排序。默认的词法排序会将它们按正确的顺序排序,因为十六进制数字0-9a-f在标准字符集中是按该顺序出现的。
如果你有一些数字有不同的位数,或者你在字母数字上混合了大小写,那么你最好的选择可能是转换成十进制,按数字排序,然后再转换回来。如果你有GNU版本的awk,你可以用它来做转换:
在示例输入上运行,我得到以下输出:
说明:
-v name=value
告诉awk
设置将存在于程序上下文中的变量;这是一种方便的方法来注入值,而不必处理复杂的引用,因为字符串插入到代码中。2但是有些变量名是特殊的;FS
告诉awk
使用什么(F)字段(S)分隔符将输入行拆分成字段,OFS
告诉它在打印行时使用什么(O)输出字段分隔符。-v{,O}FS=,
序列只是将两个变量设置为相同值的快捷方式;它通过shell的大括号扩展扩展为-vFS=, -vOFS=,
。因此,在awk程序中,每一行都将被预先用逗号拆分为字段,各个字段的值位于变量$1
、$2
中,依此类推。当这些变量被更改时,它们将在打印出来时用逗号重新连接在一起。在
-v
选项之后传递给awk
的字符串中的代码是要运行的awk
程序。针对每行输入检查每个条件,然后如果条件为真,则对该块进行评估。如果出现的块没有条件,则在每行上运行该块;如果出现一个条件而没有块,它将导致打印出当前行--或者如果其它块已经进行了修改,则打印出由OFS连接的当前行的字段。上面的程序使用两个默认值;每个都以没有条件的程式码区块开始,因此会在每一行执行,并以没有程式码区块的条件结束:1,它始终为true,因此在代码块进行更改后,每一行都将打印出来。
第一个
awk
程序使用strtonum
函数将第一个字段转换为十进制。BSD awk(也是macOS自带的)没有strtonum
,我们必须在字段值前面加上“0x”,这样strtonum
就知道把它当作十六进制,但是一旦它是一个数值,它就会被打印成十进制。所以awk
的输出和输入是一样的,除了第一个字段被转换成十进制。我们将其输入
sort
,让它按第一个(-k1,1
)逗号分隔(-t,
)字段进行数字排序(-n
),然后将排序后的输出输入第二个awk
,它使用sprintf
函数将第一个数字字段转换回十六进制。ej83mcc02#
输入:
转型一号班轮:
说明:
awk
添加新的第一列作为十六进制数的十进制表示sort
在第一列上以数字表示cut
删除第一列