我有由脚本自动生成的 csv 文件,但对于收到的某些记录(行项目),我需要搜索第 2 列,如果值包含“*.app”,我需要将“INVALID”打印到第 2 列中记录匹配并将单元格向右移动。
数据文件示例:
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK //Example of good line
www,biz.app,tony,7-11-17,06:22,ok //Example of bad line
...
Wanted output:
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK
www,INVALID,biz.app,tony,7-11-17,06:22,ok //Example of fixed line
...
我没有成功尝试 awk、sed 和 if 语句,但没有得到我需要的结果
e.g.
if [ awk -F',' '{ print $2 } < FILE' ] == "*.app" ; then ; echo "INVALID"; fi
这显然很糟糕...刚接触 bash 谢谢大家!
答案1
awk -F, -vOFS=, '$2 ~ /\.app$/ { for (i = NF + 1; i > 2; --i) $i = $(i-1); $2 = "INVALID" } 1' file >newfile
这将从newfile
.file
该awk
命令将输入和输出字段分隔符设置为逗号,然后根据.app
与值末尾的字符串匹配的正则表达式测试第二列的值。如果测试成功,记录的字段将右移一位,为字符串腾出位置INVALID
作为新的第二个字段。
尾部1
可以替换为{ print }
(它会导致输出每一行)。
对于给定的示例数据,输出文件将包含
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK
www,INVALID,biz.app,tony,7-11-17,06:22,ok
答案2
Awk
方法:
awk 'BEGIN{ FS = OFS = "," }NR > 1 && $2 ~ /.*\.app/{ $2 = "INVALID" OFS $2 }1' file
NR > 1 && $2 ~ /.*\.app/
- 如果记录号大于1
(除第一个之外的所有记录)并且第二个字段$2
与模式匹配/.*\.app/
输出:
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK
www,INVALID,biz.app,tony,7-11-17,06:22,ok
答案3
使用该GNU sed
工具,我们可以按如下方式解决这个问题:
sed -e '
1!s/,/\n&/2
/\.app\n/s/,/,INVALID,/
s/\n//
' file.csv
读作:
° Only for lines that are not the first, meaning, skip the header from being considered for processing, whilst for the others, place a marker at the second occurrence of the comma.
° Any line that has the 2nd field terminating in a .app append the string INVALID after the first field.
° Now take away the marker.
° N. B. Lines whose 2nd field doesn't comprise *.app are passed on unmodified.