创建具有文件重复性的新文件
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 的操作系统)下的可移植脚本,最简单的方法是在脚本的开头添加一行:
如果您的脚本使用 ksh
或 bash
:
export PATH="$(getconf PATH):$PATH"
如果您的脚本使用旧版 /bin/sh
:
PATH="`getconf PATH`:$PATH"; export PATH
要使您的交互式 shell 运行 处于兼容模式,您还可以将其中一行添加到正确的初始化文件中(.profile
、.bash_profile
、 ...)
这应该可以解决您的命令遇到的问题。
我有下面的命令,它根据第二列提取重复的行(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 的操作系统)下的可移植脚本,最简单的方法是在脚本的开头添加一行:
如果您的脚本使用 ksh
或 bash
:
export PATH="$(getconf PATH):$PATH"
如果您的脚本使用旧版 /bin/sh
:
PATH="`getconf PATH`:$PATH"; export PATH
要使您的交互式 shell 运行 处于兼容模式,您还可以将其中一行添加到正确的初始化文件中(.profile
、.bash_profile
、 ...)
这应该可以解决您的命令遇到的问题。