views:

108

answers:

2

I am reading one property file which contains some file paths using shell script. Now depending on this file path I want to create name of zip file. Something like this...My property file contents::

path=tmp/inputs/logs/abc
path=tmp/backup/inte/xyz
destpath=abc/xyz

Now I am able to create file name as abc.zip and xyz.zip as:

paths=`grep path myfile.property |cut -d= -f2`
d_path=`grep destpath myfile.property |cut -d= -f2`     
filename=$d_path/$(basename $paths).zip

Which create abc.zip and xyz.zip. But I want to create name by taking last three parameter of the path. Something like this...

  • for abc.zip it should be inputs_logs_abc.zip and
  • for xyz.zip it should be backup_inte_xyz.zip

EDIT

Paths=`grep path myfile.txt |cut -d= -f2`

d_Path=`grep destpath myfile.txt |cut -d= -f2`

for s_Path in $Paths

   do

       prefix=${Paths%%/*/*/*}    
       without_prefix=${Paths##${prefix}/}
       slashes_to_underscores=${without_prefix//\//_}
       zipFile=$d_Path/${slashes_to_underscores}.zip
       find $s_Path -type f -name "*.log" | xargs zip -mT $zipFile -@

   done

Above is my code.By using this i am not able to achieve my target. Can somebody help me in this?

A: 

Does this work for you?

paths=$(grep path myfile.property |cut -d= -f2)
d_path=$(grep destpath myfile.property |cut -d= -f2)
extname=$(echo $paths | sed 's%^.*/\([^/]*/[^/]*/[^/]*\)$%\1%;s%/%_%g')
filename=$d_path/$extname.zip

The first substitute in the sed script now removes everything before the last three components of the path - not removing anything if there are only two - and the second maps the remaining slashes to underscores. Note that you will have problems if the paths have trailing slashes (though you can add a substitute to remove them). You'd also get a leading underscore in the name if it contained, say, /tmp/pattern. You might need to worry about using '[^/][^/]*' in place of just '[^/]*' to ensure that there aren't empty component names (and then you might worry about doubled slashes too). And GNU Sed provides you with extra regex features so you might be able to use '[^/]+' instead.

Jonathan Leffler
Thanx for reply..but the path which i given here all are just examples..so we cannot predict any keyword in path.However path and d_path keywords in property file are final.
MAS1
+2  A: 

Since you are using bash (this would also apply to zsh or similar), you could use its in-built parameter substitution.

% path=tmp/inputs/logs/abc
% prefix=${path%%/*/*/*}
% without_prefix=${path##${prefix}/}
% slashes_to_underscores=${without_prefix//\//_} 
% filename=${slashes_to_underscores}.zip        
% echo $filename           
inputs_logs_abc.zip

You can prepend ${d_path} as appropriate to ${filename}. $path in my example is hard-coded, you will assign this in a loop over ${paths}, as per fahd's answer to your previous question.

  • ${var//exp/sub} replaces all instances of exp in $var with sub
  • ${var%%exp} trims any instance of exp from the right of var
  • ${var##exp} trims any instance of exp from the left of var

Edit (following some sleep and clarification):

prefix=${path%%/*/*/*} does a greedy match from right-to-left. If you have a '/' before tmp this will break (this is not what you said you were doing in your comment, but would give that result). Change this line to be prefix=${path%/*/*/*} (single percentage sign: non-greedy) and this should fix longer and shorter paths.

Edit 2 (following update to question):

I can see three problems:

  1. "Paths=grep path myfile.txt |cut -d= -f2" # This matches "destpath=abc/xyz", you should probably grep for '^path=' to get just lines that start with "path=".
  2. You are using ${Paths} twice inside the loop where you should use (the curiously-named) ${s_Path}.
  3. You are still using the greedy match in the prefix= line. See my previous edit.
Johnsyweb
@Johnsyweb,thanx for your reply. But above code cretae file name with full path,means if path is path=tmp/xyz/inputs/logs/abc then it is creating file name as tmp_xyz_inputs_logs_abc.zip. But i want only last three directories name as inputs_logs_abc.zip.
MAS1
I use your code in loop(fahd's answer) which is present in my previous question.
MAS1
The code in my example was copied directly from the command-line. `path=tmp/inputs/logs/abc` is the input and `inputs_logs_abc.zip` is the output as demonstrated. Please append the full code that you now have as an edit to your question so that I can see where the bug is.
Johnsyweb
I have pasted my code as EDIT in question.Can you please check why it is not working with me.My requirement of above code hope you know from my previous question which you mentioned in your answer.
MAS1
Edited my answer accordingly. I won't write your code for you, though. That is not what this site is for!
Johnsyweb
Actually i was pasted my code in EDIT by making some changes. So the problem no 2 u mentioned is typo. About problem number 1 and 3, i have make changes as for now i use grep for ^path, and for greedy match i use prefix=${path%/*/*/*/}(adding one single slash at end). for this i have done changes in my myfile.txt also as path=tmp/inputs/logs/abc/(Here also i add one slash at end). So its working fine for me.Thanks for your help!!!Many Thanks.
MAS1