我想使用Unix排序但有时我想要字段分隔符,如果用一对封闭分隔符括起来不被视为字段分隔符。例如,让我们看一下基本情况,然后再看一下具体情况:
基本案例:
"xyz"|27
"abc"|15
"xyz"|25
当我执行以下命令时:
sort -t' |' -k1,1 -k2,2n test1.txt
我得到了我想要的东西:
"abc"|15
"xyz"|25
"xyz"|27
现在让我们看看带有转义字符对的第二种情况<>提供:
"x<|>yz"|27
"abc"|15
"xyz"|25
如果我运行相同的命令,我会得到一些我不想要的东西:
"abc"|15
"x<|>yz"|27
"xyz"|25
有没有告诉unix排序,如果&lt;&gt;或{}或()或甚至像(&lt;)这样的奇怪对,然后忽略封闭分隔符对内的实际字段分隔符?实际的字段分隔符将始终是管道。
我的目标是:
"abc"|15
"xyz"|25
"x<|>yz"|27
答案 0 :(得分:0)
简短:sort
没有这样做。
long:您可以通过对数据进行前/后过滤来解决此问题,以使字段在列中对齐。如果我只使用命令行sort
,我会使用sed
对文件进行预处理,以便分隔符为tab
字符(在POSIX中,在任何可打印之前)字符)。排序后,用垂直条替换tab
将是另一个sed
- 命令。
对于&#34;主要是&#34;,主要的缺陷是在某些语言环境中,各种标点符号基本上都被忽略了。
答案 1 :(得分:0)
我不这么认为,但你可以:
<|>
使用awk:
$ awk 'BEGIN{FPAT="([^|]+|(\"[^\"]+\"))";OFS="|"}{i=$1;gsub(/<.*>/,"",i);print i,$2,$1}' file | sort -t\| -k1 -k2 | awk 'BEGIN{FPAT="([^|]+|(\"[^\"]+\"))";OFS="|"}{print $NF,$2}'
"abc"|15
"xyz"|25
"x<|>yz"|27
解释(1.和2.):
$ awk 'BEGIN{FPAT="([^|]+|(\"[^\"]+\"))";OFS="|"}{i=$1;gsub(/<.*>/,"",i);print i,$2,$1}' file
输出:
"xyz"|27|"x<|>yz"
"abc"|15|"abc"
"xyz"|25|"xyz"
代码解释:
BEGIN {
FPAT="([^|]+|(\"[^\"]+\"))" # define fields to allow field separators in quotes
OFS="|" # output field separator to |
}
{
i=$1 # copy first field to var i
gsub(/<.*>/,"",i) # remove "escaped" part
print i,$2,$1 # output
}
管道到sort -t\| -k1 -k2
输出(3.):
"abc"|15|"abc"
"xyz"|25|"xyz"
"xyz"|27|"x<|>yz"
代码解释:
... # see previous explanation
{
print $NF,$2 # print last first then second (original order)
}
并且(4.)的结果就在那里。