LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   Expanding file names in a script? ../blah -> /home/blah (https://www.linuxquestions.org/questions/linux-general-1/expanding-file-names-in-a-script-blah-home-blah-161504/)

Bebo 03-23-2004 04:33 PM

Expanding file names in a script? ../blah -> /home/blah
 
Hello,

Is there a way to expand "the dots" in file/directory names to the proper path, so that the reference is absolute and not relative? For instance, if I use find ., all the files and directories in the resulting listing will start with ./. If I instead want to change this to the full path, is there a special command for it, or do I have do write my own script function?

Cheers,

Bebo

Tinkster 03-23-2004 05:19 PM

find -printf "$PWD/%P\n"


Cheers,
Tink

Bebo 03-24-2004 02:57 AM

Thanks Tink, but no, this doesn't work all the way. If I would invoke it like this find ../../usr/local/bin/ -printf "$PWD/%P\n", or even like this find ../../usr/local/bin/ -printf "%h/%P\n", I would get the wrong path.

Looking_Lost 03-24-2004 04:01 AM

The $PWD format he gave was to overcome the find . (current directory) problem, if you want the format of output for any other directory without the leading dot you can just give it the full path to the directory, why use .. ?

find /usr/local/bin

Looking_Lost 03-24-2004 04:12 AM

your find ../../usr/local/bin/

should work like this

find ../../usr/local/bin | cut -f5- -d'.'

just change the value of -f5 to f7 or whatever depending on how many ../ you put in

Bebo 03-24-2004 04:30 AM

Yes, of course you're right, Looking_Lost. Hm... OK then, I guess I picked another bad example. So, what if I want to do the same thing from /usr/src/linux instead? Then I could issue find ../../local/bin/, and I would not get the full path either by using the -printf stuff or cut.

At the moment, it seems the way to solve this is to pick out the first part, with all the ../'s, cd to that place wherever it is, pwd, and cd back. I was hoping there would be a better way.

Looking_Lost 03-24-2004 04:55 AM

I dunno, you seem to be making life hard for yourself :)

Bebo 03-24-2004 07:30 AM

Yeah maybe :) What I'm trying to do is that I want to be able to check that any two files aren't the same, just by checking their paths and names.

Tinkster 03-24-2004 11:36 AM

Just out of curiosity: does my archiving script
work on your machine? I see that VisionZ has
problems with it :}

[edit]
back to your problem:
Have you considered using locate?
It returns the full path ...
[/edit]


Cheers,
Tink


Bebo 03-24-2004 01:16 PM

Hi Tink,

I tested your second script and it worked just fine. Heh, I just realized that I was writing almost exactly the same script - oops ;) It seems VisionZ has problems with the file command, so your script won't work in his cygwin environment. I had to change my first script to sidestep that.

Well anyway, no I haven't tried to use locate *testing* Well, if I point it at a certain file, like locate ../../usr/local/bin/blah, then it won't return anything. Doesn't surprise me, though, since noone would need to use locate if they already knew the location of the file :)

Well, if there isn't a better way than dirname - cd - pwd - cd, then that'll have to do...

Tinkster 03-24-2004 03:27 PM

Try

locate \/usr\/local\/bin\/blah


Cheers,
Tink

Bebo 03-24-2004 03:41 PM

Well, locate works if the search string doesn't contain any dots, but returns nothing if it does.

What I'm looking for is a command or anything that will expand any stupid directory referal; even ./../../usr/local/../share.

<EDIT>
BTW, thanks a lot for trying to help me on this :)
</EDIT>


Looking_Lost 03-24-2004 04:35 PM

oops

Looking_Lost 03-24-2004 04:37 PM

Well, I battered this together in java.

Limitations: only prints out filenames and paths, can be changed easily to print out dirs
resolves links to their full paths, doesn't print the link rather the thing it's
pointing too
ignores broken links

if you can be bothered you can compile it with gcj

gcj --main=listf listf.java -o listf
or plain old java compiler

save it as listf.java

Code:


import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class listf{

        static void getListing(File dirPath)
        {
               
                    File[] directoryListing=dirPath.listFiles();
                       
                    if( directoryListing != null){

                              Arrays.sort(directoryListing);
                                                       
                               
                        for(int i=0, j=directoryListing.length; i<j; i++){

                        if((directoryListing[i].canRead())
                            && (directoryListing[i].isFile()))               
                            try{       
                                  System.out.println(directoryListing[i].getCanonicalFile());               
                              }catch(IOException ioe) { }
                             
                          if((directoryListing[i].canRead()) && (directoryListing[i].isDirectory()))
                                      getListing(directoryListing[i]);
                        }

                  }
            }
       
    public static void main(String args[])
        {
       
                if(args.length!=1){
                        System.err.println("Usage: listf directory");
                        System.exit(1);
                        }
                       

                File theDirectory=new File(args[0]);
                       
                if(theDirectory.canRead())
                        getListing(theDirectory);       
          }       
}


Bebo 03-24-2004 05:01 PM

Wow! :D That's a very nice thingy you've got there, but it still doesn't do what I want :)

I think I'll settle for something like this:
Code:

redir()
{
  BASEDIR=`pwd`

  SEARCHFILE=`basename $1`
  cd `dirname $1`
  SEARCHDIR=`pwd`
  cd $BASEDIR

  echo "$SEARCHDIR/$SEARCHFILE"
}

...unless someone's got a shorter way to do it.

Thanks a bunch guys :)

Tinkster 03-24-2004 06:13 PM

Quote:

full_path.C
Code:

#include <iostream>

// includes for the qt-libraries
#include <qfileinfo.h>
#include <qstring.h>

int main( int argc, char *argv[])
{
  QString filename;
  QFileInfo fi = QString(argv[1]);
  if ( fi.exists())
    {
      filename = fi.absFilePath();
      cout << filename ;
      return 0;
    }
  return 1;
}

Compile with
Code:

g++ -I/usr/lib/qt/include -L/usr/lib/qt/lib -lqt-mt full_path.C -o full_path
or where ever Qt stuff lives on your system) ;}


Demo:
Code:

[tink@diggn:~/test]$ cd /usr/local/lib
[tink@diggn:/usr/local/lib]$ ~/test/full_path  ../share/ImageMagick/../aclocal
/usr/local/share/aclocal[tink@diggn:/usr/local/lib]$ ~/test/full_path  ~/test/../documents
/home/tink/documents[tink@diggn:/usr/local/lib]$


Note that "/home/tink/documents[tink@diggn:/usr/local/lib]$" in
the output is NOT an error ... and if you don't want it to
do this, fix it by appending << endl to the cout statement ;)

I think that's what you wanted? :D



Cheers,
Tink


P.S.: Qt rocks!! ;)

Bebo 03-25-2004 04:53 PM

Again, wow! :) Thanks Tink, that is what I wanted. But, oh I'm so stupid... Ever heard of the -ef test? It checks if two files are the same... Now I can solve VisionZ's problem :)

Tinkster 03-25-2004 05:09 PM

Ummm ... -ef checks for a hard link. Not for
file identity? In other words, whether to file
descriptors point to the same inode?


Cheers,
Tink

Bebo 03-25-2004 05:27 PM

Err, maybe? :) Good or bad? :scratch: ;)

Looking_Lost 03-26-2004 06:04 AM

You could just use

cmp


which works on binary and text files.

ruind 03-29-2004 04:44 PM

why not just use realpath?

-michael

Bebo 03-29-2004 04:50 PM

Does that work in shell scripts?

ruind 03-29-2004 04:53 PM

yes, assuming it's installed on your system.

-michael

Bebo 03-29-2004 05:30 PM

Thanks a lot for the suggestion. Hm, it seems I don't have it. But on the other hand, from the man page it seems like a C command.

LOL, look at this - from the man page:
Quote:

BUGS
Never use this function. It is broken by design since it
is impossible to determine a suitable size for the output
buffer.
OK, so... I guess I won't :)

ruind 03-29-2004 05:39 PM

Quote:

Originally posted by Bebo
Thanks a lot for the suggestion. Hm, it seems I don't have it. But on the other hand, from the man page it seems like a C command.

LOL, look at this - from the man page:

OK, so... I guess I won't :)

you are indeed looking at the man page for a c function of the same name. (man section 3, if i remember correctly). the command i am referring to is obviously not installed on your system, but its man page would be located in section 1, if it were.

on a side note, the reason that the c routine's man page says that it is broken is because it is impossible to know ahead of time that a particular path name will be small enough to alloc enough memory to hold it. thus, even if you alloc PATH_MAX (or whatever) space for the output of your path, you may overflow it, which is obviously a security risk. however, you can't avoid this problem, no matter which routine you choose for the purpose.

-michael


All times are GMT -5. The time now is 08:50 AM.