我有一个unix文件Err_Call_sipregtracking.csv如下
colnum~filename~date~fieldnum~name~value
15~YYYYMMDD_BDACA_SELFRELATIVE_ARN~30MAR2016:00:00:00~1~BDA_CA_Code~1
15~YYYYMMDD_BDACA_SELFRELATIVE_ARN~30MAR2016:00:00:00~2~ARN_Code~2
15~YYYYMMDD_BDACA_SELFRELATIVE_ARN~30MAR2016:00:00:00~544~ALL~0
15~YYYYMMDD_BDACA_SELFRELATIVE_ARN~30MAR2016:00:00:00~544~ALL~0
这里的分隔符是~
。
我想将name列的不同值变为变量
我要求的输出是:
'BDA_CA_Code','ARN_Code','ALL'
请帮助我实现这一目标。我试过这个
cat Err_Call_sipregtracking.csv | awk -F'~' '{print $5}' | uniq
输出是:
name
BDA_CA_Code
ARN_Code
ALL
但我不想在结果中使用标题,我也希望它们用引号和逗号分隔。
答案 0 :(得分:4)
这里的关键是将值存储在数组中,然后打印所有元素:
$ awk -F'~' 'NR>1{item[$5]} END {for (i in item) print i}' file
ARN_Code
BDA_CA_Code
ALL
请注意使用NR>1
跳过标题。
然后,您可以使用printf "\047%s\047\n", i
打印包含单引号的元素,因为print "\047hello\047"
打印'hello'
:
$ awk -F'~' 'NR>1{item[$5]} END {for (i in item) printf "\047%s\047\n", i}' file
'ARN_Code'
'BDA_CA_Code'
'ALL'
要将这些项目连接到以逗号分隔的项目列表中,只需在从第二项开始的每个项目之前打印一个逗号(credits to Ed Morton):
for (i in item) printf "%s\047%s\047", (++c>1 ? "," : ""), i
print ""
看到它的实际效果:
$ awk -F'~' 'NR>1{item[$5]} END {for (i in item) printf "%s\047%s\047", (++c>1 ? "," : ""), i; print ""}' file
'ARN_Code','BDA_CA_Code','ALL'
答案 1 :(得分:3)
awk
是你的朋友:
$ var=$(awk -v FS="~" 'NR>1 && !($5 in field){printf "\047%s\047,",$5;field[$5]}' Err_Call_sipregtracking.csv)
$ var="${var%,}" #Stripping the trailing comma
$ echo "$var"
'BDA_CA_Code','ARN_Code','ALL'
备注强>
\047
作为单引号。请参阅revision history。答案 2 :(得分:3)
$ awk -F'~' 'NR>1 && !seen[$5]++{printf "%s\047%s\047", (NR>2 ? "," : ""), $5} END{print ""}' file
'BDA_CA_Code','ARN_Code','ALL'
答案 3 :(得分:1)
这可能不是很优化,但有效:
tail -n+2 Newfile.csv | awk -F'~' '{$5="\""$5"\""; print $5}' | uniq | tr '\n' ',' | sed 's/\,$/\n/'
如果您想要单引号:
tail -n+2 Newfile.csv | awk -F'~' '{a = "'"'"'"; print a $5 a}' | uniq | tr '\n' ',' | sed 's/\,$/\n/'
说明:
tail -n+2 Newfile.csv
省略了第一行awk -F'~' '{$5="\""$5"\""; print $5}'
提取第5列,并用引号括起来(对于单引号,请注意报价打印有多么复杂,可能有办法解决这个问题)uniq
删除重复项tr '\n' ','
用逗号替换换行符sed 's/\,$/\n/'
删除最后一个逗号,并用换行符替换它(为了输出可读性)答案 4 :(得分:0)
您可以使用sed 1d
跳过第一行,使用cut
获取第5个字段,并使用printf
对唯一排序结果进行格式化:
printf "'%s'\n" $(sed 1d Err_Call_sipregtracking.csv | cut -d~ -f5 | sort -u)
这并不能满足您将其作为一条线路的要求:
printf "'%s'," $(sed 1d Err_Call_sipregtracking.csv | cut -d~ -f5 | sort -u)|sed 's/,$//'
答案 5 :(得分:0)
您的命令是正确的,但稍微修改一下,如下所示:
cat Err_Call_sipregtracking| awk -F'~' '{print $5}' | uniq|sed 1d | sed -n -e 'H;${x;s/\n/,/g;s/^,//;p;}'