AWK 一个衬垫将三个字段合并到一个文件中

AWK 一个衬垫将三个字段合并到一个文件中

我有一个文件,其中的记录(行)具有两种类型的字段分隔符|!如下所示:

Name|Age|Physics|Chemistry|Maths|English|Batch!Year!AdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS!2021!1001!A!75
Student2|72|63|60|50|75|EWS!2021!1002!A!85
Student3|72|63|60|50|75|EWS!2021!1002!A!85

如何合并下面给出的Batch,YearAdmisnNo字段?

请注意,为了简洁起见,我显示了一小部分有用字段,而我的真实文件有许多此类相关字段。我想要删除两个或三个!标记的该字段不是最后一个,可以是 49 左右字段总数中的任何字段(6 或 7)。

Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
    Student1|81|65|70|80|88|EWS20211001!A!75
    Student2|72|63|60|50|75|EWS20211002!A!85
    Student3|72|63|60|50|75|EWS20211002!A!85

我请求了awk,但是任何合理的标准命令都是受欢迎的。

答案1

$ awk -F '|' 'BEGIN { OFS = FS } { sub("!", "", $NF); sub("!", "", $NF) }; 1' file
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85

这用于从输入的最后一个分隔字段中awk删除前两个字符。!|

NF在代码中使用任意数字代替awk可以影响除最后一个字段之外的其他字段。


假设只有最后一个字段包含!字符,使用sed

$ sed -e 's/!//' -e 's///' file
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85

!这将删除每行的第一个。然后它第二次执行完全相同的替换,!同时删除第二次。


!反转每行并连续两次删除第三行,然后再次反转生成的行。这允许其他|- 分隔字段也包含!字符。

$ rev file | sed -e 's/!//3' -e 's///3' | rev
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85

答案2

$ cat in | while read -r line ; do line="${line/\!/}" ; echo "${line/\!/}"; done
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85

答案3

使用 GNU awk 作为第四个参数split()

$ awk '{n=split($0,f,/[|!]/,s); s[7]=s[8]=""; for (i=1;i<=n;i++) printf "%s%s", f[i], s[i]; print ""}' file
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85

答案4

此任务非常适合在sed不拆分字段的情况下将第 7 个字段与下一个字段合并:

sed -E 's/|\|!//7' file

再次运行会将第 7 个(最初是第 8 个)与其下一个合并。完全:

sed -Ee 's/|\|!//7' -Ee 's/|\|!//7' file

或者更短的时间(由 Philippos 建议),因为如果第一次替换,则第二次替换将会发生:

sed -E 's/\||!//7;s///7' file

-E用于可移植性,即扩展正则表达式。

输出:

Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85

请注意,第一次替换后,第 8 个字段变成了第 7 个字段,因此我们7再次使用它。这就像做一样sed '' file | sed ''

此外,这里的不同字段分隔符也很方便,并且可以调整以合并几乎所有相邻字段。

相关内容