6

I want to ignore all hidden files, but especially .git and .svn ones when searching (and later replacing) files, not I have found that the most basic way to exclude such hidden files described in many online tutorials doesn't work here.

find . -not -name ".*"

will also print hidden files.

The script I'm trying to write is

replace() {
    if [ -n "$3" ]; then expr="-name \"$3\""; fi
    find . -type f \( $expr -not -name ".*" \) -exec echo sed -i \'s/$1/$2/g\' {} \;
    unset expr
}
user1273684
  • 1,559
  • 15
  • 24

2 Answers2

11

The thing is -not -name ".*" does match all files and directories that start with anything but "." - but it doesn't prune them from the search, so you'll get matches from inside hidden directories. To prune paths use -prune, i.e.:

find $PWD -name ".*" -prune -o -print

(I use $PWD because otherwise the start of the search "." would also be pruned and there would be no output)

Joni
  • 108,737
  • 14
  • 143
  • 193
  • Thank you, but I'm still a little lost - why does `find $PWD -name '.*' -prune -o -name '*.c' -type f -print` work but not `find $PWD -name '.*' -prune -o $expr -type f -print` with `expr="-name '*.c'"`? – user1273684 Jun 03 '13 at 16:06
  • 1
    The quotes you embed in the value of `expr` are not removed after `expr` is expanded; they are treated literally. – chepner Jun 03 '13 at 16:31
  • Also consider `find . -path "*/.*" -prune -o -print`, which works and prints relative paths. – Ciro Santilli OurBigBook.com Feb 21 '14 at 14:25
  • 1
    NB. When using `-prune`, you shouldn't leave off the `-print` at the end as you normally would, as it changes the semantics of the command when used with `-prune`. – BallpointBen Aug 23 '21 at 13:27
0

correct version

replace() {
        if [ -n "$3" ]; then expr=-name\ $3; fi
        find $PWD -name '.*' -prune -o $expr -type f -exec sed -i s/$1/$2/g {} \;
        unset expr
}
user1273684
  • 1,559
  • 15
  • 24