题
我有一个包含这种路径的文件:
C:\bad\foo.c
C:\good\foo.c
C:\good\bar\foo.c
C:\good\bar\[variable subdir count]\foo.c
和我想获得以下文件:
C:\bad\foo.c
C:/good/foo.c
C:/good/bar/foo.c
C:/good/bar/[variable subdir count]/foo.c
注意的是,非匹配路径不应该被修改。
我知道如何使用sed固定数量的子目录中做到这一点,但一个变量号给我找麻烦。事实上,我将不得不使用很多s/x/y/
表达式(多达最大深度...不是很优雅)。
可能使用awk,但这种神奇的是超出了我的能力。
仅供参考,我需要这种伎俩来纠正一个cygwin平台一些gcov的二进制文件。
我处理的二进制文件;因此,我可能有以下类型的数据:
bindata\bindata%bindataC:\good\foo.c
应译为:
bindata\bindata%bindataC:/good/foo.c
在第一\
必须不能被翻译,尽管它是在同一行上。
不过,我刚才检查了我的.gcno
文件,在编辑本书,它看起来像所有的路径侧有零,所以最下方的答案应该适合。
解决方案
sed -e '/^C:\\good/ s/\\/\//g' input_file.txt
其他提示
我建议你看看cygpath
工具,其路径名从一种格式转换为另一种。例如我的机器上:
$ cygpath `pwd`
/home/jericson
$ cygpath -w `pwd`
D:\root\home\jericson
$ cygpath -m `pwd`
D:/root/home/jericson
下面是一个Perl实现的,你问什么:
$ echo 'C:\bad\foo.c
C:\good\foo.c
C:\good\bar\foo.c
C:\good\bar\[variable subdir count]\foo.c' | perl -pe 's|\\|/|g if /good/'
C:\bad\foo.c
C:/good/foo.c
C:/good/bar/foo.c
C:/good/bar/[variable subdir count]/foo.c
它可以直接与字符串,所以它会在任何地方工作。你可以用cygpath
结合起来,但它仅适用于具有该路机:
perl -pe '$_ = `cygpath -m $_` if /good/'
(因为我没有C:\好我的机器上,我得到这样C:goodfoo.c
输出如果您的机器上使用真实的路径,它应该能够正常工作。)
您想替换“/
”所有“\
”,但只在符合良好的目录路径的行。既sed和awk将让你这样做通过具有LHS(匹配)的表达仅挑选具有正确的道路的行。
一个平凡的sed脚本来做到这一点看起来像:
/[Cc]:\\good/ s/\\/\//g
有关一个文件:
c:\bad\foo
c:\bad\foo\bar
c:\good\foo
c:\good\foo\bar
您将得到以下的输出:
c:\bad\foo
c:\bad\foo\bar
c:/good/foo
c:/good/foo/bar
下面是我会怎么做在AWK:
# fixpaths.awk
/C:\\good/ {
gsub(/\\/,"/",$1);
print $1 >> outfile;
}
然后,使用该命令运行它:
awk -f fixpaths.awk paths.txt; mv outfile paths.txt
也跟好又猛砸一些帮助:
#!/bin/bash
cat file | while read LINE
do
if <bad_condition>
then
echo "$LINE" >> newfile
else
echo "$LINE" | sed -e "s/\\/\//g" >> newfile
fi
done
尝试此
sed -re '/\\good\\/ s/\\/\//g' temp.txt
或这
awk -F"\\" '{if($2=="good"){OFS="\/"; $1=$1;} print $0}' temp.txt
不隶属于 StackOverflow