作者donkeychen (Bad_To_The_Bone)
看板RegExp
标题[问题] 请教mac sed里面\数量的问题
时间Mon Mar 24 15:47:05 2014
环境 mac osx
使用 sed
filename内容
-----------------
I\ am\ John\ you\ are\ Mary
I\\ am\\ John\\ you\\ are\\ Mary
-----------------
请问一下 我用
sed -i "" s/"I\\\ am\\\ John"/Oh/g filename
-----------------
与
sed -i "" s/"I\\\\\ am\\\\\ John"/Oh/g filename
---------------------
都能将第二行取代成
Oh\ you\ are\ Mary
第一行指令标色
sed -i "" s/"I
\\\ am
\\\ John"/Oh/g filename
-----------------
对应I\ am
\ John\ you\ are\ Mary
这个我可以理解
第二行我原本是要拿来取代两个斜线的 I\\ am\\ John\\ you\\ are\\ Mary的
但是实际上测试要取代两个斜线的得下指令
sed -i "" s/"I\\\\\\\ am\\\\\\\ John"/Oh/g filename
------------------------
想请教一下 "\\\\\ " 与 "\\\\\\\ "
-------- ----------
在这边是怎麽对应的呢
感谢大家
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 210.59.147.226
※ 编辑: donkeychen 来自: 210.59.147.226 (03/24 15:47)
※ 编辑: donkeychen 来自: 210.59.147.226 (03/24 15:52)
1F:推 LPH66:基本上这些多余的 \ 都是给 shell 看的, regexp 并没有对 \ 03/24 16:55
2F:→ LPH66:有特殊的处理; 空白前面加 \ 也是为了告诉 shell "这个空白 03/24 16:56
3F:→ LPH66:是我的参数的一部份, 不是分隔参数用的" 03/24 16:56
4F:→ LPH66:regexp 里的 \ 只有在後面跟着一些特殊字元时 (如小括号) 03/24 16:57
5F:→ LPH66:才有用, 所以後者其实送给 sed 的是三个 \ 03/24 16:57
配合fjm31714大大说的我才看懂
感谢LPH66大大
6F:→ LPH66:就是为了要把第一个 \ 的这个意义 escape 掉 03/24 16:58
7F:→ LPH66:(以上是照印象啦, 没时间查说明书有错还请指正) 03/24 16:59
8F:→ donkeychen:喔喔 LPH66大的意思是 指令还先被shell拆一层 03/24 17:04
9F:→ donkeychen:哎呀我试到都眼花了 一直在那边数 PRINT出来 @.@; 03/24 17:05
10F:→ donkeychen:用 sed -i "" 's/\\\\/Oh/g' filename 就简单的取代两 03/24 17:17
11F:→ donkeychen:个\ 只是遇到要取代'的就又出现瓶颈>< 03/24 17:21
12F:→ donkeychen:如果要取代' 我是用 s/"\'"/Oh/g 03/24 17:22
13F:→ fjm31714:为什麽我看不太懂你的 sed 指令 Orz 好多 " 03/26 17:40
14F:→ fjm31714:字串会先被 shell 拆过没错,用其他语言也是这样 03/26 17:41
16F:→ fjm31714:我是写像这样@@ sed -i "s/I\\\ am\\\ John/Oh/" file 03/26 17:47
这边我补充一下 -i "" 是说直接取代档案 不产生备分档
如果原档名是 lalala.txt
取代时下指令 -i try regexp lalala.txt
会把还没改过的东西存到lalala.txttry里面
与正规表示无关 所以最前面的-i "" 没有mac的可以不用特别去管他
我把我原文正规的部分用红线标记
希望对阅读有帮助^^;
17F:→ fjm31714:然後你可以印出取代指令 echo "s/I\\\ am\\\ John/Oh/" 03/26 17:47
这边的结果是印出
s/I\\ am\\ John/Oh/
我猜您的意思是说 因为整个指令会先被shell接收处理後才给sed程式
所以先把"正规表示式" 丢给echo 看shell如何处理"正规表示式"
这边看起来是\\ 被变成\了
18F:→ fjm31714:就知道 regex 长怎样 另外 "" 里的空白原本是不用 escape 03/26 17:49
19F:→ fjm31714:可是如果这样写 "s/I\\ am\\ John/Oh/" sed 拿到会变 03/26 17:50
20F:→ fjm31714:"s/I\ am\ John/Oh/" 在 regex 里 \ 用来逃脱东西如果没 03/26 17:51
21F:→ fjm31714:有这个逃脱他就会找原本那个字元这边就会是空白 03/26 17:51
如同大大说明的
我将问题在这边整理一下
原档案
=======================================================
I\ am\ John\ you\ are\ Mary
I\\ am\\ John\\ you\\ are\\ Mary
=======================================================
以
""包裹正规表示式
指令行1个\: sed -i "" s/
"I\ am\ John
"/Oh/g filename
-------------
shell拆过给sed: I\ am\ John
对sed来说\ 没用
要比对的对象是: I am John
比对结果: no matched
=======================================================
指令行2个\: sed -i "" s/
"I\\ am\\ John
"/Oh/g filename
---------------
shell拆过给sed: I\ am\ John
对sed来说\ 没用
要比对的对象是: I am John
比对结果: no matched
=======================================================
指令行3个\: sed -i "" s/
"I\\\ am\\\ John
"/Oh/g filename
-----------------
shell拆过给sed: I\\ am\\ John
要比对的对象是: I\ am\ John
比对结果: line1 matched
=======================================================
指令行4个\: sed -i "" s/
"I\\\\ am\\\\ John
"/Oh/g filename
-------------------
shell拆过给sed: I\\ am\\ John
要比对的对象是: I\ am\ John
比对结果: line1 matched
=======================================================
指令行5个\: sed -i "" s/
"I\\\\\ am\\\\\ John
"/Oh/g filename
---------------------
shell拆过给sed: I\\\ am\\\ John
对sed来说\ 没用
要比对的对象是: I\ am\ John
比对结果: line1 matched
=======================================================
指令行6个\: sed -i "" s/
"I\\\\\\ am\\\\\\ John
"/Oh/g filename
-----------------------
shell拆过给sed: I\\\ am\\\ John
对sed来说\ 没用
要比对的对象是: I\ am\ John
比对结果: line1 matched
=======================================================
指令行7个\: sed -i "" s/
"I\\\\\\\ am\\\\\\\ John
"/Oh/g filename
-------------------------
shell拆过给sed: I\\\\ am\\\\ John
要比对的对象是: I\\ am\\ John
比对结果: line2 matched
=======================================================
指令行8个\: sed -i "" s/
"I\\\\\\\\ am\\\\\\\\ John
"/Oh/g filename
---------------------------
shell拆过给sed: I\\\\ am\\\\ John
要比对的对象是: I\\ am\\ John
比对结果: line2 matched
整理上面的指令
发现shell会把两个\\ 拆成一个\
然後单独的\後面接着东西也会被当作单独\来看
(如果单独的\後面没接东西 就会变成多行指令当作一行进入下一行等你输入)
於是在这个情况使用
""包裹正规表示式 最正确的指令是
要比对内容一个\ 在指令行双引号内要有4个\
所以我原本用5个\ 跟7个\ 都是歪打正着
应该是用4个\ 跟8个\
此外如果用
''来包裹正规表示式的情况如下
=======================================================
指令行1个\: sed -i "" s/
'I\ am\ John
'/Oh/g filename
-------------
shell拆过给sed: I\ am\ John
对sed来说\ 没用
要比对的对象是: I am John
比对结果: no matched
=======================================================
指令行2个\: sed -i "" s/
'I\\ am\\ John
'/Oh/g filename
---------------
shell拆过给sed: I\\ am\\ John
要比对的对象是: I\ am\ John
比对结果: line1 matched
=======================================================
指令行3个\: sed -i "" s/
'I\\\ am\\\ John
'/Oh/g filename
-----------------
shell拆过给sed: I\\\ am\\\ John
对sed来说\ 没用
要比对的对象是: I\ am\ John
比对结果: line1 matched
=======================================================
指令行4个\: sed -i "" s/
'I\\\\ am\\\\ John
'/Oh/g filename
-------------------
shell拆过给sed: I\\\\ am\\\\ John
要比对的对象是: I\\ am\\ John
比对结果: line2 matched
22F:→ fjm31714:以上是我的看法,有错请指教 >< 03/26 17:52
感谢大大 您说的用echo来看解决我的疑惑
包括了" 与 ' 的问题
处理 "
echo
"\"
"
echo
'"
'
均可
处理 '
echo
"'
"
才可以
※ 编辑: donkeychen (210.59.147.226), 04/14/2014 11:00:38