![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-08-05 04:39 |
共 48,038 主题排行 / 350,123 发帖 / 今日 0 篇 / 48,251 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » awk中使用gsub再配合|出現奇怪現象? |
| 可打印版本 2,176 / 21 |
| 第16楼 qzwqzw | 发表于 2007-06-22 12:33 |
| 银牌会员 发帖 636 积分 2,343 | |
|
使用^取消"的转义作用即可
|
|
| 第17楼 pillow | 发表于 2007-06-23 13:22 |
| 初级用户 发帖 82 积分 196 | |
Originally posted by qzwqzw at 2007-6-22 12:33: 唉,都被"給搞蒙了,我還把^加到了“裏面……居然問出來這種白癡問題, 不過透過這個問題,倒是把qzwqzw之前講的一句話理解了: “首先\是awk的转义符号,而不是cmd的;其次cmd的引号匹配是成对的” 所以"CN中前面的"並沒有被他前面的\在cmd中escape,而只是在gawk中escape; 因而CMD並沒找到和這個"匹配的",就出現了後面|失效的問題。 新問題: 雖然我不是專業編程,但上學時的書裏講的也的確是像qzwqzw講的那樣,“从前到后,或者从左到右",但您後來又有“也就是说在cmd中每个引号总是与离它最近的引号进行匹配”這樣的說明,就有疑問產生了,"CN中的"為什麼不是與(/\"CN=/,\"\")中逗號後面的"匹配,而是與1.txt後面的那一個匹配呢? 換個問法也就是說,既然英文半角的"不會像全角下的“”這樣分左右,而又是從左向右的執行,解釋器是如何判定哪兩個是相互匹配的那一對? [ Last edited by pillow on 2007-6-23 at 02:01 PM ] |
|
| 第18楼 pillow | 发表于 2007-06-25 08:21 |
| 初级用户 发帖 82 积分 196 | |
|
問得有些羅唆,只是知道"要放在|的前面,可是為什麼放在1.txt後面
gawk "{gsub(/\"CN=/,\"\");print}" 1.txt" | gawk -F"(" "{print $1}" "CN=/,\"\");print}" 1.txt"這一段為什麼不會對語句解釋產生岐義呢? |
|
| 第19楼 qzwqzw | 发表于 2007-06-25 16:41 |
| 银牌会员 发帖 636 积分 2,343 | |
"CN中的"為什麼不是與(/\"CN=/,\"\")中逗號後面的"匹配,而是與1.txt後面的那一個匹配呢? 这个理解是错误的 在cmd中,"CN中的"是与最前的"{gsub中的"相匹配的 这就是所谓的“最近匹配原则” 也可以理解为第(2*n)个的引号与(2*n-1)个引号相匹配(n为自然数) 即所谓的“前单配后双”原则 这种原则实现起来是最为简单的 不需要使用栈来保存"的层级 大约只需要做个开始与结束的标记就可以了 遇到第一个引号标记引号串开始 空格、Tab、分号等所有分界符和其它一些转义字符失效 直到遇到第二个引号 标记引号串结束 分界符等重新生效 如果再遇到第三个引号 则分界符等再次失效 直到下一个引号出现 如此反复 如果引号串之间没有出现分界符 则所有引号串以及其间的串被认作一个串 ----------------------- 对于这行gawk "{gsub(/\"CN=/,\"\");print}" 1.txt" | gawk -F"(" "{print $1}" cmd首先将它理解为五个串 1、gawk 2、"{gsub(/\"CN=/,\"\");print}" 1.txt" 3、| 4、gawk 5、-F"(" 6、"{print $1}" 而最有疑义的第2个串是由下面几个子串组成的 2-1、"{gsub(/\" 2-2、CN=/,\ 2-3、"\" 2-4、);print} 2-5、" 1.txt" 几个子串之间因为没有空格等分界符 所以被认为是一个字符串 并作为参数传给了gawk 至于gawk如何分析这个串就是Gawk内部的事了 ----------------------- 因此,据我的理解 那个gawk句子也可以改作以下几种形式 而不会让cmd产生误解 gawk "{gsub(/\"CN=/,\"\");print}"" 1.txt | gawk -F"(" "{print $1}" gawk {gsub(/\"CN=/,\"\");print} 1.txt" | gawk -F"(" "{print $1}" 上面两句cmd仍然将gawk 到 | 之间的部分认作一个串 下面两句cmd会则将它认作两个串,第二个串是 1.txt gawk "{gsub(/\"CN=/,\"\");print} 1.txt | gawk -F"(" "{print $1}" gawk {gsub(/\"CN=/,\"\");print}" 1.txt | gawk -F"(" "{print $1}" 至于会让gawk是否会产生歧义 因为没有测试环境不太肯定 前面两句应该是没有什么问题的 后面两句则可以存疑 而这样的句子很可能是不行的 gawk "{gsub(/\"CN=/, \"\");print}" 1.txt" | gawk -F"(" "{print $1}" 因为逗号后多了一个空格 而且这个空格正好位于2*n与2*n+1之间的引号中 因此cmd将它视作参数分界符 而将"{gsub(/\"CN=/, \"\");print}" 1.txt"分成了两个串 2、"{gsub(/\"CN=/, 2+1、\"\");print}" 1.txt" 而Gawk应该是不支持将匹配模式写在两个串中的 [ Last edited by qzwqzw on 2007-6-25 at 05:07 PM ] |
|
| 第20楼 lxmxn | 发表于 2007-06-25 17:58 |
| 版主 发帖 4,938 积分 11,386 | |
Originally posted by qzwqzw at 2007-6-25 16:41: 感谢 qzwqzw 的见解。 我这里有环境测试,所以做了下面这几个测试:
在gawk的所有参数两边加上"":
测试成功。
这个运行时间长而没有结果,还是在gawk的整个参数两边加上"":
这个同样是运行时间长且没有结果,还是加"":
具体其它的方案没有做过多的测试 推荐这个贴子要好好看看 http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=4#pid1511745 昨天看了一下,很有启发,其中提到了Hard Quote和Soft Quote,虽然是Linux的环境,但是对于理解命令行的解析执行还是很有启发性的。 [ Last edited by lxmxn on 2007-6-25 at 06:00 PM ] |
|
| 第21楼 qzwqzw | 发表于 2007-06-26 10:37 |
| 银牌会员 发帖 636 积分 2,343 | |
|
^ unterminated string的尖角号对的是上一行的print}后的"
刚开始看了半天没看明白 终于去下了个Gawk实际测试 才反应过来是论坛的空格比英文字母要窄 导致文本对齐的效果发生了变化 ---------------------------------------------------------------- ——“运行时间长且没有结果” 这是在等待你的输入 输入一些字符可以看到一些效果 按Ctrl+Z和回车结束输入 很显然,gawk没有从cmd传给它的命令行中找到要操作的文件 所以才从标准输入端(也就是控制台中的键盘)读取文本 ---------------------------------------------------------------- 对于出现问题的语句 gawk "{gsub(/\"CN=/,\"\");print}"" 1.txt | gawk -F"(" "{print $1}" 从cmd角度分析,它将命令行以|为界限拆分成两句 1、gawk "{gsub(/\"CN=/,\"\");print}"" 1.txt(包括紧随其后的一个空格) 2、 gawk -F"(" "{print $1}" 然后cmd将gawk "{gsub(/\"CN=/,\"\");print}"" 1.txt传递给了gawk 而gawk则以不同的方式再次解析了这个串 被\字符esacape掉的引号被忽略 所以{gsub前的引号只有与print}后的引号匹配 那么是第一个引号,还是第二个引号呢? 看看这句 gawk "{gsub(/\"CN=/,\"\");print}" " 1.txt gawk: cmd. line:1: fatal: cannot open file ` 1.txt ' for reading (No such file o r directory) 很明显gawk匹配的是第一个引号 也就是说它同cmd一样是采用的“最近匹配原则” 事实上对于引号这种由同样字符构成的字符对 采用“最远匹配原则”处理起来将是很麻烦的 而且没有多少实际意义 ---------------------------------------------------------------- 那么cmd与gawk的不同在哪里呢? 他们的不同就在于gawk多忽略了三个由\前缀的引号 从而导致字符串合并与切分发生了戏剧般的变化 对于gawk "{gsub(/\"CN=/,\"\");print}"" 1.txt(包括紧随其后的一个空格) cmd把它分成 1、gawk 2、"{gsub(/\"CN=/,\"\");print}"" 3、1.txt 而gawk把它分成 1、gawk 2、"{gsub(/\"CN=/,\"\");print}"" 1.txt 由于第二个串中的 1.txt 缺少与前面引号相匹配的引号 所以提示“未终止串” 对gawk "{gsub(/\"CN=/,\"\");print}" " 1.txt gawk把它分成 1、gawk 2、"{gsub(/\"CN=/,\"\");print}" 3、" 1.txt 由于gawk从第三个串中取操作文件名 而名字前面加空格的文件并不存在 所以提示“不能打开文件” 所以,下面的句子将是正确的 gawk {gsub(/\"CN=/,\"\");print} "1.txt cmd中将此句分成 1、gawk 2、{gsub(/\"CN=/,\"\");print} "1.txt gawk则又分成 1、gawk 2、{gsub(/\"CN=/,\"\");print} 3、"1.txt -------------------------------------------- 至于那篇帖子中的Hard Quote和Soft Quote 那应该是Unix shell的概念 跟gawk关系不大 而cmd中就没有这样的概念 [ Last edited by qzwqzw on 2007-6-26 at 10:51 AM ] |
|
| 第22楼 lxmxn | 发表于 2007-06-27 01:54 |
| 版主 发帖 4,938 积分 11,386 | |
Originally posted by qzwqzw at 2007-6-26 10:37: 嗯,的确是这样,当时没有想到它会接受标准输入,所以就妄加推断了。 看了兄的分析之后,又明白了许多了,多谢。 |
|
| 上一页 1 2 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |