如何阻止awk处理文件时在末尾添加额外换行符?
问题描述
我有一个待处理的Apex类文件:
public class Controller { public class Model{ public void init() { for ... { if ... { } } } } @AuraEnabled public String y; }
用于处理该文件的脚本如下:
class=force-app/main/default/classes/Controller.cls echo $class awk '\ { print; }' $class > $class.copy mv $class.copy $class
但这个脚本执行后,会在文件末尾添加一个多余的换行符,导致文件在版本控制系统中被标记为修改(仅换行符变化):
public class Controller { public class Model{ public void init() { for ... { if ... { } } } } @AuraEnabled public String y; } // 这里多出了不必要的换行符
我试过两种方案都无效:
- 尝试通过判断行号打印前一行,结果生成了空文件:
class=force-app/main/default/classes/Controller.cls echo $class awk '\ { if ($NR > 1) { print x; } x = $0 }' $class > $class.copy mv $class.copy $class
- 尝试使用
getline函数,同样没有解决问题:
class=force-app/main/default/classes/TasksController.cls echo $class awk '\ { if (getline <= 0) { printf; } else { print; } }' $class > $class.copy mv $class.copy $class
请问有没有可行的方法,避免处理后的文件末尾被添加换行符?
可行解决方案
方法1:精准控制输出的awk脚本
核心逻辑是缓存前一行内容,仅在非首行前输出换行,最后一行直接用printf输出(不带自动换行),完全匹配原文件的结尾格式:
class=force-app/main/default/classes/Controller.cls echo $class awk 'NR>1{printf "%s\n", prev} {prev=$0} END{printf "%s", prev}' "$class" > "$class.copy" mv "$class.copy" "$class"
- 第2行及以后的内容,先打印缓存的上一行内容并追加换行
- 每次循环将当前行存入
prev变量 - 脚本结束时,直接输出最后一行内容(无额外换行),完美复刻原文件结构
方法2:直接用cat复制文件(仅单纯复制场景)
如果你的需求只是复制文件而不需要做其他处理,cat不会额外添加换行符,是最直接的方式:
class=force-app/main/default/classes/Controller.cls echo $class cat "$class" > "$class.copy" mv "$class.copy" "$class"
方法3:调整awk的输出逻辑
将print替换为printf,手动控制换行时机,仅在非第一行前输出换行:
class=force-app/main/default/classes/Controller.cls echo $class awk '{if (NR > 1) printf "\n"; printf "%s", $0}' "$class" > "$class.copy" mv "$class.copy" "$class"
- 第一行直接输出内容
- 从第二行开始,先输出换行再输出内容,确保最后一行不会多出换行符
内容的提问来源于stack exchange,提问作者Patlatus
相关产品推荐
相关产品推荐

