0

I have the following code:

  #bin/sh
  symbolic=''
  target=''
  ls -la | grep "\->" | while read line
  do
      target=${line##* }
  done

which will print out all targets files (where symbolic links point to).

Now, I would like to add the following constraints:

  1. parse the symbolic link file name (the word before ->) into the var "symbolic". (I would like to treat it as the 3rd last word of the string)
  2. only parse the symbolic link which points to a valid/existing place.

If I don't want to use "echo | awk", are there any other ways to achieve this?

Thanks!

Update & Final Solutions

  #bin/sh
  find . -maxdepth 1 -type l -xtype d | while read line
  do
      symlink=$line
      target=$(readlink line)
  done
Tom Lau
  • 109
  • 1
  • 7
  • 1
    See [Why you shouldn't parse the output of ls(1)](http://mywiki.wooledge.org/ParsingLs). – pjh Sep 10 '18 at 18:49
  • Apart from the usual problems with parsing the output of `ls`, the code above will fail on directories that contain files with names like `X->Y`. – pjh Sep 10 '18 at 18:54

2 Answers2

1

You can use find to list the valid symlinks in the current directory:

find . -maxdepth 1 -type l -xtype f

Note the value of the -xtype argument, which indicates what type of file the link links to. In this example, I've used f for regular file. If needed, you can replace this with another of the find types like d for directory.

Alex Howansky
  • 50,515
  • 8
  • 78
  • 98
0

This Bash code will list all symlinks in the current directory that reference existing targets:

shopt -s nullglob   # Handle empty directories
shopt -s dotglob    # Handle files whose names start with '.'

for file in * ; do
    if [[ -L $file && -e $file ]] ; then
        printf '"%s" is a symlink to an existing target\n' "$file"
    fi
done

If you need to get the target of a symlink, the readlink command does it on many systems:

target=$(readlink -- "$file")
pjh
  • 6,388
  • 2
  • 16
  • 17