Getting canonical path with sed


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Getting canonical path with sed
# 1  
Old 05-10-2016
Getting canonical path with sed

Hi there,

Please read the preliminary notes:
Code:
readlink does the same ....... I know
realpath does the same ....... I know
awk can do it ................ I know
perl can do it ............... I know
You're losing time ........... I know

I wrote the following script that I think prints a canonical path without following symbolic links.
It's supposed to work with any filename including space, tabs, carriage return, etc.
Can anyone think of any path that wouldn't resolve to a canonical form with this script?

Thanks for your help.

Code:
filename=$1

# Squeeze double slashes.
filename="$(echo "$filename" | sed -r 's#/+#/#g')"

# Strip special '.' directory entries.
filename=$(echo "$filename" | sed -r ':a;s#^\./##;s#/\./#/#g;s#/\.$#/#;ta')

# Strip special '..' directory entries.
filename=$(echo "$filename" | sed -r ':a;$!N;$!ba;:b;s#^/\.\./#/#;s#/([^/.]|[^/.][^/]|[^/][^/.]|[^/]{3,})/\.\.(/|$)#/#;tb')

# 2  
Old 05-10-2016
Not listed in your list of "I knows": I think you could do this with shell builtins, and I don't mean the bash/ksh dependent ones.

Also, if it's supposed to work with any filename "including space, tabs, etc" then it fails at line one, where you don't put double quotes around $1.
# 3  
Old 05-10-2016
I'm using bash and I usually don't need to quote variable when doing a strict variable=$variable operation. What shell fails to do that?

My command:
Code:
a=space" "tab$'\t'newline$'\nend'; echo "$a" | cat -A; b=$a; echo "$b" | cat -A

My result:
Code:
space tab^Inewline$
end$
space tab^Inewline$
end$

I like your point about shell builtins. I foresee how to do it with the first two command and will post my result. Can you think of any way to do the third one with shell builtins?

---------- Post updated at 17:28 ---------- Previous update was at 17:25 ----------

Code:
# Squeeze double slashes.
while true; do
    new=${filename//\/\//\/}
    [[ "$new" = "$filename" ]] && break
    filename=$new
done

# Strip special '.' directory entries.
filename=${filename##./}
while true; do
    new=${filename//\/.\//\/}
    [[ "$new" = "$filename" ]] && break
    filename=$new
done
filename=${filename%%/.}


Last edited by chebarbudo; 05-10-2016 at 12:33 PM..
# 4  
Old 05-10-2016
You are using shell builtins only available in very new shells.

Code:
#!/bin/sh

OLDIFS="$IFS" ; IFS="/"
VAR="$1"

# Split a//b/c/d/e into $1=a, $2="", $3=b, $4=c, ...
# Note NOT quoted, we depend on shell splitting here
set -- $VAR

# S is what gets appended to O every loop between sections.
# It starts blank unless we know the path is absolute.
S="" ; O="" ; [ -z "$1" ] && S="/"

while [ "$#" -gt 0 ]
do
        case "$1" in
        "")     ;; # Skip blanks, which mean doubled slashes
        [.])    ;; # Skip single dots, which mean same-dir
        [.][.])  # Double-dot means strip off last path segment
                TMP="$*" ; S2="" ; set -- $O ; O=""
                # Re-assemble path, up to but not including last segment
                while [ "$#" -gt 1 ] ; do O="${O}${S2}${1}" ; S2="/" ; shift ; done
                set -- $TMP     # Re-split remaining tokens
                ;;
        # Add segment to O
        *)      O="${O}${S}${1}"; S="/" ;;
        esac
        shift
done

IFS="$OLDIFS"

echo "$O"

# 5  
Old 05-11-2016
Impressive!
Thanks Corona688
My notes:
  1. If path is / or ., it becomes empty which makes it impossible to differentiate the root directory from the current directory.
  2. If a path starts with ../, that first element is stripped. But ../brother and brother are not the same address.
I'm working on an edit and will submit as soon as I can.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

What is wrong with: echo $PATH | sed s/:/\\n/g

Hello all! I am on Mac (10.8.4) and my shell tcsh (man says version: Astron 6.17.00). Just to precise my tcsh: echo $LC_CTYPE UTF-8 I want to replace all ':' with a new line, to get all paths on one line. I don't find a way to make my shell accept the "\n" My start was: echo... (17 Replies)
Discussion started by: marek
17 Replies

2. Shell Programming and Scripting

find and replace a path with sed?

Hi, I am attempting to find the path /subject/grin* and replace it with /subject/$i My attempt: for i in $(ls) do sed -e 's:"/subjects/grin.*":"/subjects/$i.*":g' and several variants with no luck. Please help. Thanks! (8 Replies)
Discussion started by: JC_1
8 Replies

3. Shell Programming and Scripting

How to remove a directory path in a file using sed

Hi, I want to remove a directory path from a file starting with the bracket using sed command. eg. (cd /man/abc/def ; \ aaaaa bbbb (cd /man/aaaa/aa; \ op. aaaaa bbbb The "(cd /man" is to be consideres as the start. I tries the below thing, but it didnt worked. Can anyone help.... (3 Replies)
Discussion started by: vdhingra123
3 Replies

4. Shell Programming and Scripting

sed/awk for extracting directory from file path

Hi, I have following path: set file_path = D:/forums/prac/somedir/new1/file1.txt or set file_path = E:/new/forums1/prac/somedir/new2/file2.txt I need to grep "somedir" from file path. In this case preceding directory "prac" remains same for both the paths, but directories preceding... (7 Replies)
Discussion started by: sarbjit
7 Replies

5. Shell Programming and Scripting

Path a variable to sed that includes a path

Hi I'm trying to select text between two lines, I'm using sed to to this, but I need to pass variables to it. For example start="BEGIN /home/mavkoup/data" end="END" sed -n -e '/${start}/,/${end}/g' doesn't work. I've tried double quotes as well. I think there's a problem with the / in the... (4 Replies)
Discussion started by: mavkoup
4 Replies

6. Shell Programming and Scripting

How to get file path using sed

Hi , Hi I want to know how can i extract file path using sed? Eg: C:/folder1/abc/file.txt Now , i want C:/folder1/abc/ only, So that i can move to that directory containing that file . So how can i do it using sed? Thanks in Advance Sarbjit (2 Replies)
Discussion started by: sarbjit
2 Replies

7. Shell Programming and Scripting

Extract The File Path using SED

hi, I have a file path like usr/scripts/pass/bin and usr/scripts/pass/line I want to extract first three characters using sed Like for path usr/scripts/pass/bin i want to extract usr/scripts/pass and for path usr/scripts/pass/line i want to extract usr/scripts/pass (10 Replies)
Discussion started by: Diggi
10 Replies

8. Shell Programming and Scripting

need sed command to read a path and set to variable

I have a variable called PATH that contains a path example: /Users/rtipton/Desktop/testusers/test I need a sed command to set a variable called USER to the last directory name in that path PATH="/Users/rtipton/Desktop/testusers/test" and from that PATH i need USER to = test I know sed... (4 Replies)
Discussion started by: tret
4 Replies

9. Shell Programming and Scripting

Replace a filename with full path using sed

hi, i need to replace a line a file with a new raw device location.. original file.. /opt/sybase/ASE1502/ASE-15_0/bin/dataserver \ -d/data/TST_AKS1/sybdevices/master.dat \ -e/logs/sybase/TST_AKS1/SFO_TST_AKS1.log \ -c/apps/sybase/ASE1502/ASE-15_0/TST_AKS1.cfg \... (2 Replies)
Discussion started by: aksaravanan
2 Replies

10. Shell Programming and Scripting

SED - How to return PATH from PATH/NAME

Hi, How can I get /usr/people/me/ from /usr/people/me/file.abc with sed? Thanks... (2 Replies)
Discussion started by: cybotic
2 Replies
Login or Register to Ask a Question