I need to search (on the whole disk) and replace (where there are matches) one file with another (both in the same path).


  Folder 1
    x*.txt (good) (e.g.: xFile.txt)
    *.txt (bad) (e.g.: File.txt)

If there is a match of both files in the same path, i need to delete: *.txt (e.g.: File.txt) and rename: x*.txt (e.g.: xFile.txt) to *.txt (e.g.: File.txt)


 Folder 1
  *.txt (e.g: File.txt... old xFile.txt)

I use this command:

find -name 'x*.txt' | sed -r 'p;s/g([^\/]*.txt)/\1/' | xargs -d '\n' -n2 mv

The problem is that the command does not verify if both files exist (xFile.txt and File.txt in the same path) before executing the order

How can I solve it? Thanks in advance

  • 1
    find xfile.txt, and check [[ -f "${file#x}" ]] (which strips a leading x from the found file and checks to see if that file is present. If present, then do your switcheroo.
    – DopeGhoti
    Jun 13, 2018 at 17:25
  • 1
    Alternatively, find file.txt and check [[ -f x"$file" ]]. If the replacement is there, do your switcheroo.
    – DopeGhoti
    Jun 13, 2018 at 17:26
  • @DopeGhoti Can you explain this with a single command line?
    – acgbox
    Jun 13, 2018 at 19:28
  • 1
    What if there's a xx1.txt, x1.txt and 1.txt? Jun 13, 2018 at 20:56

2 Answers 2


With GNU tools, you could do something like:

(export LC_ALL=C
  find . -name '*.txt' -print0 |
  sed -Ez 's|/x([^/]*)$|/\1|' |
  sort -z |
  uniq -zd |
  sed -z 'h;s|.*/|&x|;G' |
  xargs -r0n2 echo mv)

That assumes there are not files whose name starts with more than one x. For instance, it won't do mv ./xx.txt ./x.txt


First, we define a function to do the work for us:

switcheroo() {
    [[ -f x"$1" ]] && mv -f x"$1" "$1"
export -f switcheroo

Now, we use find and some black magic to iterate over our foundlings:

find . -name \*.txt -execdir bash -c 'switcheroo "$0"' "{}" \;

We use find to locate all files with a .txt extension (this can be refined to suit whatever criteria you like) and in turn run them through the switcheroo process -- we use [[ ... ]] to test for the existence of the replacement file, and if it is present, use mv to effect the replacement.

  • I don't think find can run a shell function (but it's simple enough to just put inline)
    – ilkkachu
    Jun 13, 2018 at 19:48
  • Yeah, you do need to use -execdir sh '[ -f "x$1" ] && mv "x$1" "$1"' sh {} \;
    – ilkkachu
    Jun 13, 2018 at 20:01
  • Nop. syntax error
    – acgbox
    Jun 13, 2018 at 20:14
  • @DopeGhoti Your command does not solve my problem, described in the question. Thanks anyway
    – acgbox
    Jun 13, 2018 at 20:28
  • Could you explain how this does not do what you are asking after?
    – DopeGhoti
    Jun 13, 2018 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.