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?

3
  • Which shell are you scripting? What is the relevance of destpath and d_path in these snippets? Commented Oct 5, 2010 at 17:13
  • I am using bash.destpath is keyword which present in property file, according to which i read this file and store this path in d_path variable. Commented Oct 5, 2010 at 17:52
  • Then my answer should solve your problem. You can try it out at a prompt and echo the variables as you go to see how it works. Commented Oct 5, 2010 at 18:36

2 Answers 2

3

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.
Sign up to request clarification or add additional context in comments.

6 Comments

@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.
I use your code in loop(fahd's answer) which is present in my previous question.
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.
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.
Edited my answer accordingly. I won't write your code for you, though. That is not what this site is for!
|
0

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.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.