How to Find Files Excluding Symbolic Links

How to find files excluding symbolic links?

Check the man page again ;) It's:

find /path/to/files -type f

type f searches for regular files only - excluding symbolic links.

Use find to list all c/h/cc files but exclude symlinks

This definitely works for me. Are you sure your shell isn't expanding the * in your commandline? Or you didn't apply -type f to all your items:

find . -type f -and \( -name "*.c" -o -name "*.h" -o  -name "*.cc" \)

Using find to delete symbolic links except those which point to directories

As already suggested in the comments, you can use the test utility for this; but you don't need readlink because test -d always resolves symbolic links.

# replace -print with -exec rm {} +
find . -type l ! -exec test -d {} \; -print

It might be slow due to the overhead from spawning a new process for each symlink though. If that's a problem, you can incorporate a small shell script in your find command to process them in bulks.

find . -type l -exec sh -c '
for link; do
shift
if ! test -d "$link"; then
set "$@" "$link"
fi
done
# remove echo
echo rm "$@"' sh {} +

Or, if you have GNU find installed, you can utilize the -xtype primary.

# replace -print with -delete
find -type l ! -xtype d -print

How do I get a list of symbolic links, excluding broken links?

With find(1) use

$ find . -type l -not -xtype l

This command finds links that stop being links after following - that is, unbroken links. (Note that they may point to ordinary or special files, directories or other. Use -xtype f instead of -not -xtype l to find only links pointing to ordinary files.)

$ find . -type l -not -xtype l -ls

reports where they point to.

If you frequently encounter similar questions in your interactive shell usage, zsh is your friend:

% echo **/*(@^-@)

which follows the same idea: Glob qualifier @ restricts to links, and ^-@ means "not (^) a link (@) when following is enabled (-).

(See also this post about finding broken links in python, actually this demonstrates what you can do in all languages under Linux. See this blog post for a complete answer to the related question of "how to find broken links".)

How do you exclude symlinks in a grep?

Gnu grep v2.11-8 and on if invoked with -r excludes symlinks not specified on the command line and includes them when invoked with -R.

Listing non symbolic link on Windows

There are some problems in your code:

  • you need delayed expansion because you are setting (writing) and expanding (reading) the variable count within the same parenthesised block of code (namely the for /F %%a loop);
  • in your for /F %%a loop you need to state options "eol=| delims=" in order not to run into trouble with files whose names begin with ; (such would be ignored due to the default eol=; option) and those which have white-spaces in their names (you would receive only the postion before the first white-space because of the default delims SPACE and TAB and the default option tokens=1 (see for /? for details about that);
  • dir /B returns file names only, so %%a actually points to files in the current directory rather than to C:\TEMP\; to fix that, simply change to that directory first by cd;
  • to capture the output of a command (line) and assign it to a variable, use another for /F loop and set; this loop is going to iterate once only, because find /C returns only a single line; note the escaped pipe ^| below, which is required to not execute it immediately;
  • there is no comparison operator -EQU, you need to remove the - to check for equality;
  • it is a good idea to use the quoted set syntax as it is most robust against poisonous characters;
  • file and directory paths should generally be quoted since they might contain token delimiters or other poisonous characters;

Here is the fixed script:

@echo off
setlocal EnableDelayedExpansion
pushd "C:\TEMP\" || exit /B 1
for /F "eol=| delims=" %%a in ('dir /B "."') do (
for /F %%b in ('
fsutil hardlink list "%%a" ^| find /C /V ""
') do (
set "count=%%b"
)
if !count! EQU 1 del "%%a"
)
popd
endlocal

This can even be simplified:

@echo off
pushd "C:\TEMP\" || exit /B 1
for /F "eol=| delims=" %%a in ('dir /B "."') do (
for /F %%b in ('
fsutil hardlink list "%%a" ^| find /C /V ""
') do (
if %%b EQU 1 del "%%a"
)
)
popd

Since the inner for /F loop iterates always once only, we can move the if query inside, thus avoiding the definition of an auxiliary variable which is the only one we needed delayed expansion for.

How can get a list of files in a specific directory ignoring the symbolic links using python?

To get regular files in a directory:

import os
from stat import S_ISREG

for filename in os.listdir(folder):
path = os.path.join(folder, filename)
try:
st = os.lstat(path) # get info about the file (don't follow symlinks)
except EnvironmentError:
continue # file vanished or permission error
else:
if S_ISREG(st.st_mode): # is regular file?
do_something(filename)

If you still see 'filename~' filenames then it means that they are not actually symlinks. Just filter them using their names:

filenames = [f for f in os.listdir(folder) if not f.endswith('~')]

Or using fnmatch:

import fnmatch

filenames = fnmatch.filter(os.listdir(folder), '*[!~]')

How to find all symlinks to a file?

If you have GNU/BSD find just use -samefile primary.

$ find -L ~/How to Find Files Excluding Symbolic Links/ -samefile ~/How to Find Files Excluding Symbolic Links/q/a.txt 
/home/oguz/How to Find Files Excluding Symbolic Links/q/a.txt
/home/oguz/How to Find Files Excluding Symbolic Links/w/l2
/home/oguz/How to Find Files Excluding Symbolic Links/w/l1


Related Topics



Leave a reply



Submit