【问题标题】:DOS to UNIX path substitution within a file文件中的 DOS 到 UNIX 路径替换
【发布时间】:2010-10-04 12:41:29
【问题描述】:

我有一个包含这种路径的文件:

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。我编写了将 oracle 转储文件更改为 frig 表空间名称的 sed 脚本。这些文件是没有指针的流格式,因此长度的变化并不重要。

标签: sed cygwin awk gcov lcov


【解决方案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

【讨论】:

    【解决方案2】:
    sed -e '/^C:\\good/ s/\\/\//g' input_file.txt
    

    【讨论】:

      【解决方案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 的输出。如果你在机器上使用真实路径,它应该可以正常工作。)

      【讨论】:

        【解决方案4】:

        或者在优秀的 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】:

          这是我在 awk 中的做法:

          # fixpaths.awk
          /C:\\good/ {
             gsub(/\\/,"/",$1);
             print $1 >> outfile;
          }
          

          然后使用命令运行它:

          awk -f fixpaths.awk paths.txt; mv outfile paths.txt
          

          【讨论】:

            【解决方案6】:

            试试这个

            sed -re '/\\good\\/ s/\\/\//g' temp.txt

            或者这个

            awk -F"\\" '{if($2=="good"){OFS="\/"; $1=$1;} print $0}' temp.txt

            【讨论】:

              猜你喜欢
              • 2010-10-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多