Skip to main content
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following:

Stuff the looping into the spawned shell:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

Or, spawn a separate shell for each file to be tested (less efficient, potentially more readable):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

To directly remove the backup files, change this to the following for a dry run:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

Then once you're satisfied with the list of commands that gets printed, use:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

Notes:

In all of these, the find-sh argument is an arbitrary string; you could put anything there. It gets set as $0 within the spawned shell and is used for error reporting.

for a in "$@"; do is exactly equivalent to for a; do.

printf is better than echoprintf is better than echo.

Quoting is importantQuoting is important.

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following:

Stuff the looping into the spawned shell:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

Or, spawn a separate shell for each file to be tested (less efficient, potentially more readable):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

To directly remove the backup files, change this to the following for a dry run:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

Then once you're satisfied with the list of commands that gets printed, use:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

Notes:

In all of these, the find-sh argument is an arbitrary string; you could put anything there. It gets set as $0 within the spawned shell and is used for error reporting.

for a in "$@"; do is exactly equivalent to for a; do.

printf is better than echo.

Quoting is important.

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following:

Stuff the looping into the spawned shell:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

Or, spawn a separate shell for each file to be tested (less efficient, potentially more readable):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

To directly remove the backup files, change this to the following for a dry run:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

Then once you're satisfied with the list of commands that gets printed, use:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

Notes:

In all of these, the find-sh argument is an arbitrary string; you could put anything there. It gets set as $0 within the spawned shell and is used for error reporting.

for a in "$@"; do is exactly equivalent to for a; do.

printf is better than echo.

Quoting is important.

added 8 characters in body
Source Link
Wildcard
  • 37.5k
  • 30
  • 149
  • 284

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following:

Stuff the looping into the spawned shell:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

Or, spawn a separate shell for each file to be tested (less efficient, potentially more readable):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

To directly remove the backup files, change this to the following for a dry run:for a dry run:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

Then once you're satisfiedonce you're satisfied with the list of commands that gets printed, use:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

Notes:

In all of these, the find-sh argument is an arbitrary string; you could put anything there. It gets set as $0 within the spawned shell and is used for error reporting.

for a in "$@"; do is exactly equivalent to for a; do.

printf is better than echo.

Quoting is important.

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following:

Stuff the looping into the spawned shell:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

Or, spawn a separate shell for each file to be tested (less efficient, potentially more readable):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

To directly remove the backup files, change this to the following for a dry run:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

Then once you're satisfied with the list of commands that gets printed, use:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

Notes:

In all of these, the find-sh argument is an arbitrary string; you could put anything there. It gets set as $0 within the spawned shell and is used for error reporting.

for a in "$@"; do is exactly equivalent to for a; do.

printf is better than echo.

Quoting is important.

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following:

Stuff the looping into the spawned shell:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

Or, spawn a separate shell for each file to be tested (less efficient, potentially more readable):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

To directly remove the backup files, change this to the following for a dry run:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

Then once you're satisfied with the list of commands that gets printed, use:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

Notes:

In all of these, the find-sh argument is an arbitrary string; you could put anything there. It gets set as $0 within the spawned shell and is used for error reporting.

for a in "$@"; do is exactly equivalent to for a; do.

printf is better than echo.

Quoting is important.

Source Link
Wildcard
  • 37.5k
  • 30
  • 149
  • 284

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following:

Stuff the looping into the spawned shell:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

Or, spawn a separate shell for each file to be tested (less efficient, potentially more readable):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

To directly remove the backup files, change this to the following for a dry run:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

Then once you're satisfied with the list of commands that gets printed, use:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

Notes:

In all of these, the find-sh argument is an arbitrary string; you could put anything there. It gets set as $0 within the spawned shell and is used for error reporting.

for a in "$@"; do is exactly equivalent to for a; do.

printf is better than echo.

Quoting is important.