Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 我的Awk命令进行排序,但意外地忽略了重复项_Sorting_Awk - Fatal编程技术网

Sorting 我的Awk命令进行排序,但意外地忽略了重复项

Sorting 我的Awk命令进行排序,但意外地忽略了重复项,sorting,awk,Sorting,Awk,我试图按特定字段对该文件进行排序,我想在awk中完成这一切: "firstName": "gdrgo", "xxxxx": "John", "xxxxx": "John", "xxxxx": "John", "xxxxx": "John", "xxxxx": "John", "lastName": "222",dfg "xxxxx": "John", "firstName": "beto", "xxxxx": "John", "xxxxx": "John", "xxxxx":

我试图按特定字段对该文件进行排序,我想在
awk
中完成这一切:

"firstName": "gdrgo",   "xxxxx": "John", "xxxxx": "John", "xxxxx": "John", "xxxxx": "John", "xxxxx": "John",   "lastName": "222",dfg
"xxxxx": "John",    "firstName": "beto",   "xxxxx": "John", "xxxxx": "John", "xxxxx": "John",   "lastName": "111","xxxxx": "John",
"xxxxx": "John",    "firstName": "beto",   "xxxxx": "John", "xxxxx": "John", "xxxxx": "John",   "lastName": "111","xxxxx": "John",
"xxxxx": "John",   "xxxxx": "John",    "firstName": "beto2", "xxxxx": "John","lastName": "555", "xxxxx": "John","xxxxx": "John",
"xxxxx": "John",   "xxxxx": "John",    "firstName": "beto2", "xxxxx": "John","lastName": "444", "xxxxx": "John","xxxxx": "John",
"firstName": "gdrgo",   "xxxxx": "John", "xxxxx": "John", "xxxxx": "John", "xxxxx": "John", "xxxxx": "John",   "lastName": "222",dfg
"xxxxx": "John",   "xxxxx": "John",    "firstName": "beto2", "xxxxx": "John","lastName": "444", "xxxxx": "John","xxxxx": "John",
我使用以下命令:

awk -F'.*"firstName": "|",.*"lastName": "|",' '{b[$3]=$0} END{for(i in b){print i}}' sumacomando
哪些产出:

111
222
444
555
但我希望:

111
111
222
222
444
444    
555

也就是说,虽然实际输出看起来像是按需要排序的,但却意外地丢失了重复值。

您选择的字段分隔符是非常规的,也许最好改用它

awk -F'[:,]' '{for(i=1;i<=NF;i++) 
                  if($i~"\"lastName\"") 
                      {gsub(/"/,"",$(i+1)); 
                       print $(i+1)}}' file | sort
awk -F'[:,]' '{for(i=1;i<=NF;i++) 
                 if($i~"\"lastName\"") 
                    {gsub(/"/,"",$(i+1)); 
                     a[++c]=$(i+1)}} 
          END {asort(a); 
               for(k=1;k in a;k++) print a[k]}' file 
  • awk
    数组中键/索引的顺序始终是关联数组(字典),这是一个实现细节-不保证特定顺序;在您的例子中,输出恰好被排序

  • 键是唯一的,因此如果多个输入行中的
    $3
    具有相同的值,则
    b[$3]=…
    分配将相互覆盖-最后一个将获胜

因此,你:

  • 必须使用顺序索引数组来存储第三个字段值(
    $3

  • 以后必须按其值对结果数组进行排序

根据POSIX Awk规范,Awk没有内置的排序功能,但GNU
Awk
有,通过其
asort()函数启用以下解决方案:

awk -F'.*"firstName": "|",.*"lastName": "|",' '
  { b[++n]=$3 } END{ asort(b); for(i=1;i<=n;++i) print b[i] }
' sumacomando

将管道输送至
分拣
作为替代解决方案大大简化了问题:

awk -F'.*"firstName": "|",.*"lastName": "|",' '{ print $3, $0 }' sumacomando | sort -k1,1
但是,请注意,上面的纯Awk解决方案保留了重复的
$3
值之间的输入顺序,而
排序
辅助解决方案没有这样做


相反,纯Awk解决方案需要一次将所有输入存储在内存中,而
sort
实用程序经过优化,可以处理大型输入集,并根据需要使用临时文件。

@victorhernandezzero:@try:我尝试了另一种方法,希望它也能对您/所有人有所帮助。仅使用单个awk(无其他命令)


awk'/lastName/{getline;while(!$0){getline};A[$0]}END{num=asorti(A,B);for(i=1;我非常感谢你的回答,但出于不同的原因,我看起来像是完全用awk来做的;但是如果我没有找到另一个答案,我会选择你作为我的最佳答案???
gawk
awk
因为与最初的unix工具Philosophy相比,我感谢您愿意改进您的问题。您的答案的排序部分现在与我的答案中的第一个解决方案相同(除了您复制了数组,这是不必要的)。值提取部分一开始就不需要重写-OP的命令在这方面工作得很好-而且你的重写很复杂,涉及到
getline
,这很少是正确的工具。这也使得解决方案更难推广。注意:请不要在你的答案中提到OP。OP会收到答案通知抱歉,这是一个混乱,因为安装gawk但不能与nawk或awk一起本地工作。抱歉,这是一个混乱
awk -F'.*"firstName": "|",.*"lastName": "|",' '{ print $3, $0 }' sumacomando | sort -k1,1
awk '/lastName/{getline;while(!$0){getline};A[$0]} END{num=asorti(A, B);for(i=1;i<=num;i++){print B[i]}}' RS='[: ",]'   Input_file
awk '/lastName/{getline;while(!$0){getline};A[++j]=$0} END{num=asort(A, B);for(i=1;i<=num;i++){print B[i]}}' RS='[: ",\n]'  Input_file