如何在awk中静默读取单个字符变量?现有代码问题排查
问题原因
问题出在awk的文件处理机制和缓冲区特性:
- 当awk正在逐行处理目标文件时,会打开该文件的句柄并维护内部读取缓冲区,这时用
system()调用shell修改该文件(或是你用来中转输入的临时文件),awk不会自动刷新缓冲区,getline读的还是缓冲区里存的旧内容。 - 要是你复用了已经打开的文件句柄去读中转文件,awk不会重新打开文件获取新写入的内容,只会从当前指针位置继续读旧数据。
简便实现方法
不用绕文件中转的弯子,awk可以直接和终端交互,借助/dev/tty读取用户输入,同时用stty控制终端不回显输入字符,实现静默读取单个字符的要求。示例代码:
{ # 打印询问,$0是当前行的文件名 printf "是否删除该文件「%s」?[y/N] ", $0 # 关闭终端回显,实现静默输入 system("stty -echo") # 从终端读取输入到变量ans getline ans < "/dev/tty" # 恢复终端回显,别搞坏终端状态 system("stty echo") # 换行,让光标移到新行 print "" # 判断输入,执行对应操作 if (tolower(ans) == "y") { printf "删除文件:%s\n", $0 system("rm -f '" $0 "'") # 加单引号避免文件名含空格/特殊字符出问题 } else { printf "保留文件:%s\n", $0 } }
使用方式
假设你要处理的文件名列表在file_list.txt里,运行命令:
awk -f delete_confirm.awk file_list.txt
注意点
/dev/tty指向当前终端,直接读它可以避开awk默认的标准输入(不会被处理的文件占用)。- 一定要记得恢复
stty echo,不然终端会一直处于无回显状态,影响后续操作。 - 给
rm命令的文件名加单引号,防止文件名里有空格、特殊字符导致命令执行出错。
内容的提问来源于stack exchange,提问作者wildtoaster
相关产品推荐
相关产品推荐

