关于正则表达式:Bash用于将相对路径转换为绝对路径的Perl脚本

Bash & Perl script to convert relative paths to absolute paths

我有一个顶级目录路径,我想将所有相对路径递归地转换为这个目录中所有文件中的绝对路径。例如,我有这个目录结构:

1
2
3
4
5
6
7
$ tree
.
|-- DIR
|   |-- inner_level.ext1
|   `-- inner_level.ext2
|-- top_level.ext1
`-- top_level.ext2

EDOCX1[0]含量:

1
2
../../a/b/c/filename_1.txt
../../a/d/e/filename_2.txt

假设顶层dir路径为/this/is/the/abs/dir/path/

希望将EDOCX1[0]的内容转换为:

1
2
/this/is/the/abs/a/b/c/filename_1.txt
/this/is/the/abs/a/d/e/filename_2.txt

top_level.ext2含量:

1
2
cc_include+=-I../../util1/src/module1/moduleController -I../../util/src/module1/module2Controller;
cc_include+=-I../../util2/src/module2/moduleUtility;

希望将top_level.ext2的内容转换为:

1
2
cc_include+=-I/this/is/the/abs/util1/src/module1/moduleController -I/this/is/the/abs/util/src/module1/module2Controller;
cc_include+=-I/this/is/the/abs/util2/src/module2/moduleUtility;

另外,希望对dir中的文件应用相同的转换。

例如DIR/inner_level.ext1含量:

1
2
../../../a/b/c/filename_1.txt
../../../a/d/e/filename_2.txt

希望将DIR/inner_level.ext1的内容转换为:

1
2
/this/is/the/abs/a/b/c/filename_1.txt
/this/is/the/abs/a/d/e/filename_2.txt

同样适用于DIR/inner_level.ext2

写了这两个剧本。

top_level.ext1转换成功。

file_manager.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/bash
file='resolve_path.pl'
basedir='/this/is/the/abs/dir/path'

run_perl(){
    echo -e"
 File getting modified: $1"

    cp $1 tmp.in
    perl $file
    mv tmp.out $1
    rm tmp.in
}

find $basedir -type f |while read inputfile
do
    run_perl $inputfile
done

resolve_path.pl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use 5.010;
use Switch;

#******************************************************
#       Set-up Directory And Input/Output File Names
#******************************************************
our $in_file  = glob('tmp.in');
my $out_file1 = 'tmp.out';
print"Input file: $in_file
"
;

#************************************
#       Local and Global Variables
#*************************************
my $current_path ="/this/is/the/abs/dir/path";
my $temp_path = $current_path;

#************************************
#       Open Read and Write File
#************************************
open(READ, $in_file) || die"cannot open $in_file";
open(WRITE,">$out_file1") || die"cannot open $out_file1";


#******************************************************
#       Read The Input [*.out] File Line By Line
#******************************************************
while (<READ>) {
    if(/^(\.\.\/){1,}(\w+\/)*(\w+).(\w+)/){
      my $file_name = $3;
        my $file_ext  = $4;

        my @count = ($_ =~ /\.\.\//g);
        my $cnt = @count;

        my @prev_dir = ($_ =~ /\w+\//g);
        my $prev_dir_cnt = @prev_dir;
        my $file_prev_dir = join('', @prev_dir);

        $temp_path = $current_path;
        for(my $i=0; $i<$cnt; $i++){
            if($temp_path =~m/(\/.*)\/\w+/){
                $temp_path = $1;
            }
        }

        print WRITE"$temp_path"."\/"."$file_prev_dir"."$file_name"."\."."$file_ext"."
"
;

    } else {
        print WRITE"$_";
    }
}

我面临的问题:

  • 不在top_level.ext2DIR/inner_level.ext2上应用转换。因为我的Perl脚本没有正确解析../es(即cc_include+=-I即将开始)。

  • 从相对路径到绝对路径的转换不起作用适用于DIR/inner_level.ext1,错误路径附加的。

  • 如果有人能建议对我的脚本进行预期的更改,以解决上述两个问题,那将是很有帮助的。


    为什么是这两个脚本?那是低效的。

    Perl完全能够检索文件列表,并且具有简化该过程的模块以及解析和更改路径的模块。

    文件::查找-遍历目录树。

    文件::查找::规则-文件::查找的可选接口

    文件::basename-将文件路径解析为目录、文件名和后缀。

    文件::规范-可移植地对文件名执行操作