创建具有文件重复性的新文件

Create new file with duplicities of a file

我有下面的命令,它根据第二列提取重复的行(file.csv 以逗号分隔):

awk -F',' '{print }' file.csv | sort | uniq -d | grep -F -f - file.csv >file.bad

但在 Solaris 上,由于不支持 grep 命令的 -F 参数,因此此命令不起作用。

原始文件中的行示例:

"A","TEST","Other","TEST",...  
"A","TEST2","Other A","TEST2",...  
"A","TEST","Other B","TEST",...

新文件中的行示例:

"A","TEST","Other","TEST",...  
"A","TEST","Other B","TEST",...

猫sample.csv

"A","TEST","Other","TEST",...
"A","TEST2","Other A","TEST2",...
"A","TEST","Other B","TEST",...

运行 下面:

awk -F, 'NR==FNR{a[]++;next} (a[]>1)' sample.csv sample.csv > new_file.csv

new_file.csv

的内容
"A","TEST","Other","TEST",...
"A","TEST","Other B","TEST",...

我所做的是它读取样本 2 次。第一次将第 2 个字段存储在一个数组中,然后第 2 次检查第 2 个字段出现时间是否超过一次,我们打印出该行。

  • NR==FNR{a[$2]++;下一个} 将第二个字段存储在数组 a 中,然后进入下一个 record/line

  • (a[$2]>1) 第二次读取sample.csv文件时,检查数组是否多次出现第2个字段,如果第2个字段有重复,打印出第

在您的管道中显式使用 /usr/xpg4/bin/grep 而不是普通的 grep(这可能是从 /usr/bin/grep 中提取的)。

Solaris 上的 /usr/bin/grep 不支持 -F 选项(也不支持从文件读取模式的 -f 选项),但 /usr/xpg4/bin/grep 支持,根据Oracle's documentation。您甚至可能想将 /usr/xpg4/bin 放在 $PATH 的前面,以避免将来出现此问题。不过我不是 Solaris 用户,所以我不知道这样做是否合理。

此外,/usr/xpg4/bin/grep-f 标志采用文件名。我不确定它是否理解 - 作为标准输入。

要强制从标准输入读取,请将 - 替换为 /dev/stdin

您的管道现在看起来像这样:

awk -F',' '{print }' file.csv | sort | uniq -d | /usr/xpg4/bin/grep -F -f /dev/stdin file.csv >file.bad

您正在使用 Solaris 默认设置 PATH,其中一些执行的命令最终成为遗留命令,而不是 POSIX 兼容命令。要 运行 Solaris(和其他类似 Unix 的操作系统)下的可移植脚本,最简单的方法是在脚本的开头添加一行:

如果您的脚本使用 kshbash:

export PATH="$(getconf PATH):$PATH"

如果您的脚本使用旧版 /bin/sh:

PATH="`getconf PATH`:$PATH"; export PATH

要使您的交互式 shell 运行 处于兼容模式,您还可以将其中一行添加到正确的初始化文件中(.profile.bash_profile、 ...)

这应该可以解决您的命令遇到的问题。