如何将管道化Awk命令合并为单次Awk调用?
问题
我正在格式化一个输入文件,以下是文件示例及xxd命令输出:
The First 1,000,000 Primes 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53
xxd输出:
00000000: 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 00000010: 2054 6865 2046 6972 7374 2031 2c30 3030 The First 1,000 00000020: 2c30 3030 2050 7269 6d65 7320 2866 726f ,000 Primes (fro 00000030: 6d20 7072 696d 6573 2e75 746d 2e65 6475 m primes.utm.edu 00000040: 290d 0d0a 0d0d 0a20 2020 2020 2020 2020 )...... 00000050: 3220 2020 2020 2020 2020 3320 2020 2020 2 3 00000060: 2020 2020 3520 2020 2020 2020 2020 3720 5 7 00000070: 2020 2020 2020 2020 2031 3120 2020 2020 2020 11 00000080: 2031 3320 2020 2020 2020 2031 3720 2020 13 17 00000090: 2020 2020 2031 3920 0d0d 0a20 2020 2020 19 ...
我使用以下命令:
awk -v OFS="\n" '{$1=$1}1' inputfile
但会产生需要去除的空行:
The First 1,000,000 Primes 2 3 5
目前我通过管道命令解决:
awk -v OFS="\n" '{$1=$1}1' inputfile | awk '!/\r/'
请问能否仅调用一次Awk实现同样效果?
解决方案
当然可以,单次Awk调用就能完成需求,核心是在处理字段的同时处理回车符并过滤空行,以下是两种实用方法:
方法一:全局移除回车符+过滤空行
awk -v OFS="\n" '{gsub(/\r/, ""); $1=$1} $0 != ""' inputfile
gsub(/\r/, ""):全局替换掉所有回车符(\r),从根源避免空行产生$1=$1:触发Awk重新格式化行,将原空格分隔的字段用换行符(OFS)连接$0 != "":仅输出非空行,彻底清除多余空行
方法二:仅移除行尾回车符+过滤空行
如果回车符只出现在行尾,可使用更高效的行尾替换:
awk -v OFS="\n" '{sub(/\r$/, ""); $1=$1} $0 != ""' inputfile
sub(/\r$/, ""):只替换行尾的回车符,性能优于全局替换
这两种方法都无需管道第二个Awk进程,一次调用即可得到目标输出。
内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

