2017-09-16 24 views
0

私はトップレベルのdirパスを持っています。このディレクトリ内のすべてのファイルに存在する絶対パスにすべての相対パスを再帰的に変換したいと思います。例: 絶対パスへの相対パスを変換するBash&Perlスクリプト

$ tree 
. 
|-- DIR 
| |-- inner_level.ext1 
| `-- inner_level.ext2 
|-- top_level.ext1 
`-- top_level.ext2 

コンテンツtop_level.ext1の:

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

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

は、トップレベルのディレクトリのパスが/this/is/the/abs/dir/path/

がにtop_level.ext1のコンテンツを変換したいですと仮定し、私は、このディレクトリ構造を持っています

内容:top_level.ext2

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

top_level.ext2へのコンテンツを変換したい:

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の 内容:

DIR/inner_level.ext2のための同じ
/this/is/the/abs/a/b/c/filename_1.txt 
/this/is/the/abs/a/d/e/filename_2.txt 

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

がにDIR/inner_level.ext1のコンテンツを変換したいです。

この2つのスクリプトを作成しました。

top_level.ext1の変換は正常に動作しています。

file_manager.sh

#!/usr/bin/bash 
file='resolve_path.pl' 
basedir='/this/is/the/abs/dir/path' 

run_perl(){ 
    echo -e "\n 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

#!/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\n"; 

#************************************ 
#  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"."\n"; 

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

問題私が直面しています:

変換は top_level.ext2 & DIR/inner_level.ext2上に適用されていない
  1. 私のPerlスクリプトが../(すなわち、 cc_include+=-Iが最初に来ています)。

  2. の場合、相対パスから絶対パスへの変換が正しく行われず、間違ったパスが になっています。

上記の2つの問題を解決するためにスクリプトに予想される変更を提案できる人がいれば役に立ちます。

答えて

3

なぜ2つのスクリプトですか?それは非効率的です。

Perlは完全にファイルのリストを取得することができ、プロセスを簡略化するモジュールと、パスを解析して変更するモジュールを備えています。

File::Find - Traverse a directory tree.

File::Find::Rule - Alternative interface to File::Find

File::Basename - Parse file paths into directory, filename and suffix.

File::Spec - portably perform operations on file names

関連する問題