仅打印第一列唯一的行

THX*_*THX 5 awk text-processing

我正在寻找一种对列表进行排序并打印所有行的方法,其第一列仅出现一次 - 即仅匹配第一列。例如,我有一个文件,其中第一列是路径,第二列包含“类型”

/path/foo/1 footsy
/path/foo/1 barsy
/path/foo/X barsy
/path/bar/2 footsy
/path/bar/2 barsy
/path/foo/Y footsy
Run Code Online (Sandbox Code Playgroud)

(文件实际排序为-k1,1)

现在,我只想提取像

/path/foo/X barsy
/path/foo/Y footsy
Run Code Online (Sandbox Code Playgroud)

我正在考虑使用 awk 的某种方式,在那里我必须存储前一行并将前一行的第一个字段与当前行中的相应字段进行比较。但我还不知道如何完成它:(我试图调整在另一个问题中找到的解决方案,但它并没有像预期的那样工作

awk '{
  prev=$0; path=$1; type=$2
  getline
  if ($1 != $path) {
    print prev
  }
}'
Run Code Online (Sandbox Code Playgroud)

G-M*_*ca' 1

    \n
  1. awk通常读取输入的每一行并调用其上的脚本。\xc2\xa0\n您使用的情况getline很少。\xc2\xa0\n当您的脚本使用六行输入运行时,\n这是所发生情况的概述:

    \n\n
    \n

    正常读取第1行

    \n\n
    \n

    设置变量
    \n Call getline,读取第 2 行
    \n 比较变量

    \n
    \n\n

    正常读取第3行

    \n\n
    \n

    设置变量
    \n Call getline,读取第 4 行
    \n 比较变量

    \n
    \n\n

    正常读取第5行

    \n\n
    \n

    设置变量
    \n Call getline,读取第 6 行
    \n 比较变量

    \n
    \n
    \n\n

    显然这是\xe2\x80\x99 行不通的。

  2. \n
  3. 其次,您在awk代码中犯了一个常见错误。\xc2\xa0 在 中awk,\n输入中的字段被引用为\n变量被引用为。\xc2\xa0\n这与 shell 脚本不同,\n其中命令行参数是引用为\n并且变量引用为.\xc2\xa0\n您的测试$numbervariable_name$number$variable_name

    \n\n
    if ($1 != $path)\n
    Run Code Online (Sandbox Code Playgroud)\n\n

    应该

    \n\n
    if ($1 != path)\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
  5. 您的整体方法有缺陷。\xc2\xa0\n您无法\xe2\x80\x99t 识别文件中仅出现一次的字符串\n通过\xc2\xa0一次查看两行。\xc2\xa0\n我相信您可以通过一次查看三行来完成(即,\xc2\xa0by\xc2\xa0 将前行保留在变量中),\n但是这样的事情会变得复杂而混乱。\xc2\xa0\nIt\xe2 \x80\x99s 可能更容易计算出现次数。\xc2\xa0\nHere\xe2\x80\x99s 对脚本进行最小修改以 \xc2\xa0 执行此操作。

    \n\n
    awk \'{\n  if ($1 != path) {\n    if (count == 1) {\n      print prev\n    }\n    count=1\n  }\n  else count++\n  prev=$0; path=$1\n}\nEND {\n    if (count == 1) {\n      print prev\n    }\n}\'\n
    Run Code Online (Sandbox Code Playgroud)\n\n

    我删除了type,因为你从未使用过它。

    \n\n

    披露:这本质上与glenn\xe2\x80\x99s 答案的最后部分相同。

  6. \n
\n