我有一个由数据行组成的文件,其中列由给定的分隔符指定。
e.g。
20170202,ABC,USD,USD,100,20170202
20170202,ABC,GBP,USD,200,20170202
20170201,ABC,NOK,USD,300,20170204
20170131,ABC,DKK,USD,400,20170202
我想要一种打印此文件行的方法,例如,第1列是20170202,第4列是USD。同时,我想用打印输出字符包围打印输出中的那些列,以便向用户突出显示它们。
因此,在上面的示例中,只应打印第1行和第2行,并且:
目前我为每个传递的参数都有一个链式grep。
e.g。
cat myfile.txt | grep -w "20170202" | grep -w "USD"
然后将其传送到sed语句,该语句将20170202和USD用转义字符填充以对输出进行着色。
但是,在上面的示例中,第4行将失败,因为它将被错误地输出,第4列和第6列突出显示。对于第1行也是如此,第1,3,4和6列将突出显示(当我只想要1和4时)。
任何人都可以建议如何为任意选择的列进行此操作吗?
包括awk,因为我想这个解决方案可能涉及它。
答案 0 :(得分:1)
在 awk 中,您可以将字段替换为彩色字段。下面的脚本应该 做好工作
# cat 42000109
1. 20170202,ABC,USD,USD,100,20170202
2. 20170202,ABC,GBP,USD,200,20170202
3. 20170201,ABC,NOK,USD,300,20170204
4. 20170131,ABC,DKK,USD,400,20170202
# awk -v FS=" |," '$2=="20170202" && $4=="USD"{$2="\033[1;31m"$2"\033[1;39m";$4="\033[1;31m"$4"\033[1;39m";print}' 42000109
1. 20170202 ABC USD USD 100 20170202
#fields 2 and 4 will be highlighted
有关bash颜色的更多提示,请查看[ this ]链接。
修改强>
如果开头的数字不存在,那么下面的内容应该
# awk -v FS=',' -v OFS=',' '$1=="20170202" && $4=="USD"{$1="\033[1;31m"$1"\033[1;39m";$4="\033[1;31m"$4"\033[1;39m";print}' 42000109
20170202,ABC,USD,USD,100,20170202
20170202,ABC,GBP,USD,200,20170202
# #fields 1 and 4 will be highlighted
答案 1 :(得分:1)
考虑首先构建您想要的颜色的地图,然后使用它,例如:
$ cat tst.awk
BEGIN {
n = split("\
red 31 \
green 32 \
reset 39 \
", tmpA)
for (i=1; i<=n; i+=2) {
colors[tmpA[i]] = ("\033[1;" tmpA[i+1] "m")
}
FS=OFS=","
}
function color(field,clr) {
$field = (colors[clr] $field colors["reset"])
}
($1=="20170202") && ($4=="USD") {
color(1,"red")
color(4,"green")
}
{ print }
$ awk -f tst.awk file | cat -v
^[[1;31m20170202^[[1;39m,ABC,USD,^[[1;32mUSD^[[1;39m,100,20170202
^[[1;31m20170202^[[1;39m,ABC,GBP,^[[1;32mUSD^[[1;39m,200,20170202
20170201,ABC,NOK,USD,300,20170204
20170131,ABC,DKK,USD,400,20170202
答案 2 :(得分:0)
使用 sed (有点难以阅读所有\
)
sed -e '/^\(20170202\)\(,\([^,]*,\)\{3\}\)\(USD\)\(,.*\)/!d' -e 's//\\\1\\\2\\\4\\\5/' YourFile
# OR into a more generic form
sed -e '/^\('${YourDate}'\)\(,\([^,]*,\)\{3\}\)\('${YourCurrency}'\)\(,.*\)/!d' -e 's//\\\1\\\2\\\4\\\5/' YourFile
awk 版本
awk '$1=="20170202"&&$4=="USD"{$1="\\"$1"\\";$4="\\"$4"\\";print}' FS=',' OFS=',' YourFile
相同,更通用,带注释(使用变量进行批处理)
awk -v MyDate="{YourDate}" -v MyCur="${YourCurrency} '
# Parameter assign some variable with external value of script
# if first field (col) = the date AND 4th field = Currency
$1 == MyDate && $4 == MyCur {
# replace field 1 by itself surrounded by escape char
$1 = "\\" $1 "\\"
# same for field 4
$4 = "\\" $4 "\\"
# Print line (with new content)
# default output is modified by OFS value adapted (default is space separator between field and set to , in this script)
print
}
# assign 2 varible (FS and OFS for field separator as input and output)
# before reading first availble file (YourFile)
' FS=',' OFS=',' YourFile
答案 3 :(得分:-2)
cat text file| awk -F "," '$1 ~ /20170202/ && $3 == "USD" { print }'
awk
接受当前文件的分隔符逗号“,”并将它们分开,可以通过$ 1,$ 2,$ 3等访问它们。所以我们可以根据需要尝试查看匹配是否为1美元和3美元。 $ 1匹配是通过正则表达式匹配完成的,该匹配通过运算符~
完成,正则表达式字符串保留为正斜杠/
。