![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-08-05 05:51 |
共 48,038 主题排行 / 350,123 发帖 / 今日 0 篇 / 48,251 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » awk中使用gsub再配合|出現奇怪現象? |
| 可打印版本 2,182 / 21 |
| 第1楼 pillow | 发表于 2007-06-18 17:47 |
| 初级用户 发帖 82 积分 196 | |
|
awk中使用gsub再配合|出現奇怪現象? 想對一個內容類似下面的txt處理,最後得到AA_A這樣的形式,最開始是用-F指定不同FS去切開,後來想只通過gsub兩次將不需要字符替換成""即得到答案,但第一次替換完成後再用第二次時,通道符 | 被認成了文件,請問這個是bug還是我的用法不正確?
第二個問題是我想用通本符/=/來代表/\"CN=/,但不成功,請問這種寫法是錯在哪里? "CN=AA A(中文名字1),OU=Users,OU=NNNN,DC=CCC,DC=aDDD" "CN=BB B(中文名字2),OU=Users,OU=PPPPP,DC=CCC,DC=aDDD" 我的命令,|後面的我換成了一般的打印都會提示有錯 gawk "{gsub(/\"CN=/,\"\");print}" 1.txt | gawk -F"(" "{print $1}" gawk: (FILENAME=1.txt FNR=790) fatal: cannot open file `|' for reading (Invalid argument) [ Last edited by pillow on 2007-6-18 at 05:49 PM ] |
|
| 第2楼 lxmxn | 发表于 2007-06-18 20:48 |
| 版主 发帖 4,938 积分 11,386 | |
| 第3楼 pillow | 发表于 2007-06-18 21:30 |
| 初级用户 发帖 82 积分 196 | |
Originally posted by lxmxn at 2007-6-18 20:48: 首先谢谢指导! 我又找了找awk的贴子,但没发现关于您的用法的讲解,那么就大胆猜测一下,若不对,再请您更正: 1. 当FS=多个不同符号时,则任何一个独立的符号都是FS,而不是按指定的形式连在一起的才是。 比如您用的是=( 那么就是说任何被=或(分开的都算是一个field,而不是被连着的=(才算,对吗? 2. 尽管对您的方法我已经有了推测理解,但对我问的问题仍有不解,我原来的命令是: gawk -F"(" "{ print $1 }" 1.txt | gawk -F"=" "{if ($0 !~ /!/) {print $2}}" 即显示(前面的部分 | 显示=后面不含!的部分,此时的 | 会正常工作,而没被gawk当作多个文件中的一个,而我最开始列出的命令中却不是这样,原因会是什么呢? [ Last edited by pillow on 2007-6-18 at 09:31 PM ] |
|
| 第4楼 lxmxn | 发表于 2007-06-18 22:08 |
| 版主 发帖 4,938 积分 11,386 | |
|
Re pillow:
1、如果要指定多个分隔符,要用中括号将分隔符括起来,否则gawk会认为这个字符串作为一个大的分隔符。 这两个例子输出的结果是不一样的。 2、抱歉,第二个问题的原因我也不是很明白。 |
|
| 第5楼 pillow | 发表于 2007-06-18 22:14 |
| 初级用户 发帖 82 积分 196 | |
Originally posted by lxmxn at 2007-6-18 22:08: |
|
| 第6楼 pillow | 发表于 2007-06-18 22:31 |
| 初级用户 发帖 82 积分 196 | |
|
看来还得麻烦您,
为了将space换成undeline,得到最终的AA_A形式,我对pipe进行了gsub操作,追加了| gawk "{gsub(/ /,"__");print}",整行变为: gawk "BEGIN{FS=\"[=(,]\"} $2 !~ /[!#]/{print $2}" 1.txt | gawk "{gsub(/ /,"_");print}" 但发现space没有换成undeline,而且消失了,预想中的AA_A没有出现,却变成了AAA,奇怪啊! |
|
| 第7楼 lxmxn | 发表于 2007-06-19 02:15 |
| 版主 发帖 4,938 积分 11,386 | |
|
这样试试:
|
|
| 第8楼 pillow | 发表于 2007-06-19 11:40 |
| 初级用户 发帖 82 积分 196 | |
Originally posted by lxmxn at 2007-6-19 02:15: 這次徹底懂了,action script裏面的所有“都要加escape才行, 受教了…… |
|
| 第9楼 lxmxn | 发表于 2007-06-19 19:14 |
| 版主 发帖 4,938 积分 11,386 | |
|
嗯,这是cmd和linux的shell的不同之处,只要注意这点,其它的都一样的。
|
|
| 第10楼 qzwqzw | 发表于 2007-06-20 12:26 |
| 银牌会员 发帖 636 积分 2,343 | |
|
关于这个
gawk "{gsub(/\"CN=/,\"\");print}" 1.txt | gawk -F"(" "{print $1}" 应该不难理解 这主要还是引号的问题 首先\是awk的转义符号,而不是cmd的 其次cmd的引号匹配是成对的 除非没有可以成对的引号 上句中 1.txt 前的引号恰好是单数 所以只能与 gawk -F后的引号匹配 这导致 | 的管道作用被 "" 关闭 也导致gawk后所有的字符串 都被cmd视为连续的一个参数 全部传给了第一个 gawk 所以,最终的原因就是第一个 gsub 中多了或少了一个 \" 至于怎么改,就需要根据上下文的代码进行调整了 [ Last edited by qzwqzw on 2007-6-21 at 08:19 AM ] |
|
| 第11楼 lxmxn | 发表于 2007-06-20 12:40 |
| 版主 发帖 4,938 积分 11,386 | |
|
在 qzwqzw 的解释下,修改了一下这句就可以了。
|
|
| 第12楼 pillow | 发表于 2007-06-21 00:49 |
| 初级用户 发帖 82 积分 196 | |
Originally posted by lxmxn at 2007-6-20 12:40: 在对使用引号具体问题提问前,想先问下“CMD引号必须成对出现”这样的规则在什么地方有讲?(刚才网上小搜了一下,没找到,或者请指教我应在论坛中用哪个key word查询?) 1. 我在思想上理解您和qzwqzw的解释,但对1.txt后面那个"配对十分不解。 按我先前认识中的理解," "中的东西是作为参数传给指令的,举例如下(先认为{ "}" {}外面的一对"包起来的内容,是传给CMD的参数, 外面的一对"包起来的内容,是传给gawk的参数, ()外面的一对"包起来的内容,是传给gsub的参数, 无论(){}哪个范围中的什么字符,都应在从内向外执行时失去其特殊意义,只将运行结果传给外层做下一级运算,按这个思想理解,最后就变成了 gawk "{XXXXXXXX}" 1.txt" ,最后多出来的那个",反而是多出来的…… 2. 按qzwqzw的解释,多加了个"的下面这句 gawk "{gsub(/\"CN=/,\"\");print}" 1.txt" | gawk -F"(" "{print $1}" 就会被正确的解释为 gawk "{gsub(/“CN=/,"");print}" 1.txt | gawk -F"(" "{print $1}" 这时这一句已经不再需要遵守CMD的"成双原则,即可将|认成是管道符,是吗? 但cmd识别'配对的方法,我想了半天,还是没想懂。 再请帮忙消除疑云,感谢! |
|
| 第13楼 lxmxn | 发表于 2007-06-21 01:13 |
| 版主 发帖 4,938 积分 11,386 | |
|
RE pillow:
1、 在对使用引号具体问题提问前,想先问下“CMD引号必须成对出现”这样的规则在什么地方有讲?(刚才网上小搜了一下,没找到,或者请指教我应在论坛中用哪个key word查询?) 有很多“不成文”的批处理技巧,都是微软的帮助文档和网上的教程没有的,是自己大量的实践和总结得出来的。 2、 我在思想上理解您和qzwqzw的解释,但对1.txt后面那个"配对十分不解。 我是这样理解的: 在命令行执行的每个命令,都需要经过命令解释器(cmd.exe)来预处理,其中包含对变量值的扩展,对特殊符号的转义等等,其中应该还包括对引号的匹配的检查。 例如 C:\>echo "batch|find "at"我想出现这个问题的原因,还是由于引号”不配对造成的。 3、 gawk "{gsub(/“CN=/,"");print}" 1.txt | gawk -F"(" "{print $1}" 此时命令已经被cmd解释了一次,就不再受cmd的引号匹配的原则的约束,再来由gawk进行下一步的处理。所以此时管道符号|就可以正常发挥它的作用了。 [ Last edited by lxmxn on 2007-6-21 at 01:30 AM ] |
|
| 第14楼 qzwqzw | 发表于 2007-06-21 08:30 |
| 银牌会员 发帖 636 积分 2,343 | |
|
回复一下pillow的问题
首先,我并没有提到过“引号必须成对出现”的原则 而且cmd里也不存在这条原则 在其他语法解析器中很可能存在 只是,在cmd中没有成对匹配的引号无法发挥起转义作用 这在其他语法解析器中也是一样的 ------------------------------------------------- 其次,cmd的引号的采用最近匹配原则,而非最远匹配原则 也就是说在cmd中每个引号总是与离它最近的引号进行匹配 gawk我并不熟悉 不过据我所知 大多数语法解析器都是采用与cmd相类似的原则 所以也就是不存在你所说的“从内向外执行”特征 而是从前到后,或者从左到右 [ Last edited by qzwqzw on 2007-6-21 at 08:35 AM ] |
|
| 第15楼 pillow | 发表于 2007-06-22 08:23 |
| 初级用户 发帖 82 积分 196 | |
|
这两个的区别我能理解出来了,但是“如何匹配还是没能搞懂,若许再需要实例去了解吧。
于是有个问题,比如在lxmxn的例子中,改過後的命令後來已經是要先顯示"batch",再尋找at了吧?若我一定要求顯示的是"batch,再從這個字串中尋找at,那麼應該將"放在什麼地方? (不是在鑽牛角尖,是希望弄清楚配對的方式) C:\>echo "batch|find "at" "batch|find "at" |
|
| 1 2 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |