我有一个包含这种路径的文件:
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执行固定数量的subdir,但是变量号给我带来了麻烦。实际上,我将不得不使用许多s/x/y/
表达式(尽可能多的最大深度......不是很优雅)。
可能是awk,但这种魔法超出了我的技能。
仅供参考,我需要这个技巧来纠正cygwin平台上的一些gcov二进制文件。
我正在处理二进制文件;因此,我可能会有以下类型的数据:
bindata\bindata%bindataC:\good\foo.c
应翻译为:
bindata\bindata%bindataC:/good/foo.c
第一个\
不得翻译,尽管它位于同一行。
但是,我在编辑此文本时检查了我的.gcno
文件,看起来所有路径都是零,所以下面的大部分答案都适合。
答案 0 :(得分:5)
sed -e '/^C:\\good/ s/\\/\//g' input_file.txt
答案 1 :(得分:3)
我建议您查看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:\ good,我的输出类似于C:goodfoo.c
。如果你在你的机器上使用真实路径,它应该正常工作。)
答案 2 :(得分:1)
您希望将“/
”替换为所有“\
”,但仅限于与良好目录路径匹配的行。 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
答案 3 :(得分:1)
以下是我在awk中的表现:
# fixpaths.awk
/C:\\good/ {
gsub(/\\/,"/",$1);
print $1 >> outfile;
}
然后使用以下命令运行它:
awk -f fixpaths.awk paths.txt; mv outfile paths.txt
答案 4 :(得分:0)
或者在好的'Bash:
的帮助下#!/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
答案 5 :(得分:0)
试试这个
sed -re '/\\good\\/ s/\\/\//g' temp.txt
或者
awk -F"\\" '{if($2=="good"){OFS="\/"; $1=$1;} print $0}' temp.txt