2013-03-22 104 views
1

对于这个简单的问题感到抱歉,但我在学习和尝试的四天中失明了,似乎无法使用正确的语法。Cygwin sed:使用十六进制,八进制或十进制搜索/替换一个不可打印的字符

在cygwin上使用sed,我试图用另一个不可打印的字符替换一个不可打印的ASCII字符。

这里是我的源文件,使用大写文字[方括号内]表示不可打印的ASCII字符:

myfile.txt: 

line one[LF] 
line two[LF] 
line three[LF] 
[SUBSTITUTE][LF] 
line four{LF] 
line five[LF] 
line six[LF] 
. 
. 
. 

我想用标签来代替LF类。

由于LF类的十六进制0A和标签是十六进制09我都试过了,基本做法是:

sed -i 's/\x0A/\x09/g' myfile.txt 

这改变不了什么的文件中。

当然,我已经尝试了不同的开关,如-b,-e和-r,带括号和不带,带和不带/ g,额外的反斜杠和无反斜杠,八进制和十进制符号,一路到精灵符文,绝对没有成功。

我读了一些使用'回声'而不是文件作为源的答案,他们只是困惑我,并没有工作。

其他例子使用'作弊'像实际的单词TAB,但他们阻止我学习使用数字的语法,所以我可以将它应用于其他不可打印的字符,而不仅仅是TAB。

当我尝试的 '文件' 命令,我得到:

file myfile.txt 
file.txt: data 

所以,当然我想:

sed -i -t UTF-8 's/\x0A/\x09/g' myfile.txt 

但我的sed不支持该功能-t选项。

当我试试这个:

oc -c myfile.txt 

的[LF]字符我在寻找表现为:

\n 

我也曾尝试\ 0D作为我的搜索词,没有运气无论是。

如果有人想通过显示正确的语法给我一个线索,我将非常感激。

谢谢。

回答

2

谢谢大家,我很感激那些试图帮助的人。如果StackOverflow让我,我会upvote每一次尝试帮助。

我回答我自己的问题,希望它能帮助别人。

我知道sed无法处理LF并不完全正确。它可以处理它们,但只有当它写它们。不是在阅读时。如我所愿,我不能完全按照sed完成这项工作。我喜欢sed的原地开关,这看起来比创建另一个文件更麻烦,因此吸引了我的OCD。

我的文件的格式是:

Mary(LF) 
Smith(LF) 
(SUB)(LF) 
John(LF) 
Public(LF) 
(SUB)(LF) 

,我想要的结果:

Mary(TAB)Smith(LF) 
John(TAB)Public(LF) 

所以,我想改变LF到TAB,以及LF-SUB-LF,使LF 。

我解决了我的问题,首先使用TR将所有LF换成TAB。无法为此使用sed。

# change LFs to TABs ... so grep can later treat entire file as one line 
tr '\012' '\011' <comengo.extract.txt> comengo.extract.out 
mv comengo.extract.out comengo.extract.txt 

这样,sed现在可以将整个文件视为一行。 sed只喜欢逐行处理文件,所以我把整个罚款单一线。

第二步是让sed跳入,并进行我想要的更改。我的问题的要点是“我如何表现非印刷ascii字符?”。

我以前的尝试失败了,因为我试图在sed搜索字符串中使用\ x12。现在LF已被替换,我使用了一个不间断的十六进制数字序列。

# changes (tab)(sub)(tab) to just (sub) 
sed -i 's/\x09\x1A\x09/\x1A/g' comengo.extract.tx 

然后我恢复的LF到文件通过SED,可写的LF

# (sub) to (tab)(lf) 
sed -i 's/\x1A/\x0A\x09/g' comengo.extract.txt 

这工作就像一个魅力。

1

怎么样使用tr

tr '\012' '\011' <myfile.txt> tmp.out 
mv tmp.out myfile.txt 

tr命令是纯粹的过滤器;它不会(在标准版本中,无论如何)采取任何文件名参数或支持覆盖或...

+0

谢谢,但TR不能做到就地更换。我认为cygwin sed不是真的可能吗? – 2013-03-22 20:40:08

+0

我不知道;我会用'tr'而不用担心。既然你通过删除换行符来压扁文件,我会担心使用面向行的'sed'。为什么这是“现场”完成的关键?你确定'sed'确实'有'的地方有足够的差异吗? – 2013-03-22 21:11:12

+0

我不只是想要一条鱼。我正在学习捕鱼。换句话说,我正在学习sed。我的计划要求工作要在原地完成。 sed可以搜索和替换另一个不可打印的ascii字符吗? – 2013-03-22 21:51:42

1

在sed指定换行的可移植的方法是用一个转义回报:

sed -i 's/\ 
/<tab>/g' 

与文字制表符替换文本<tab>

1

如果您使用bashksh我建议您使用shell的$'...'语法,它支持C风格的反斜杠转义。例如:

[BASH] # echo $'hello\nworld' 
hello 
world 
[BASH] # echo $'hello\x0aworld' 
hello 
world 
[BASH] # 
0

其实sed中可以匹配LF字符,如果你用在上面的--binary --null数据:

$ echo -e "Line1\r\nLine2\rLine3\nLine4\n\rLine5" | sed --null-data --binary -r -e "s/\x0d\x0a/\x0a/g" | od --format=x1a 0000000 4c 69 6e 65 31 0a 4c 69 6e 65 32 0d 4c 69 6e 65 L i n e 1 nl L i n e 2 cr L i n e 0000020 33 0a 4c 69 6e 65 34 0a 0d 4c 69 6e 65 35 0a 3 nl L i n e 4 nl cr L i n e 5 nl