Guidance requested with using fdupes

I am trying to tidy up the pictures from my phone which have been automatically uploaded to my pCloud account. I have changed phones in the period concerned so I have the pictures from both phones and these are in separate subdirectories in my pCloudDrive account. All good and as expected but…

In the process of moving my profile from the old phone to the new, all the pictures from the old phone were transferred so that when the new phone connected to pCloud I ended up with the pictures from both phones in the second phone’s subdirectory.

This is the command I am thinking but is the order correct with first phone being the original SM-G920F and new phone the A13137F, do I need to recurse and is there a prompt automatically to allow me to select a bunch, say 10 at a time?

fdupes "Samsung SM-G920F" -d "Samsung SM-A137F" 

Being dumb as usual but the pictures are irreplaceable so any help would be appreciated.

Hi and thanks, I have it and it works but I am not sure if my syntax is correct regarding which directory is first and which is deleted. Also should it be :-

fdupes -d SM-G920F SM-A137F 
or
fdupes SM-G920F -d SM-A137F

Also it is which subdirectory which is important to retain, not the file date. These were the questions I am worried about.

I am still struggling with my script, mainly because I am working with very long files names when full directory string is deep. I have been using Kate to edit my command and I have just noticed that I have a warning from Kate:- [18:04:46 LSP Client Warning] Failed to find server binary: bash-language-server

Please check your PATH for the binary

See also GitHub - bash-lsp/bash-language-server: A language server for Bash for installation or details.

I have no idea what an LSP client is but it is likely I have some binaries missing. Exactly what should I be looking for using Yast in order to install what is missing?

Sorry to be making a meal of this but I cannot make my script work. Even with some help from chatGPT all I am doing is digging a deeper hole.
The first script is here:-

#!/bin/bash

# Replace 'path/to/master/directory/A' and 'path/to/servant/directory/B' with your actual directory paths
MASTER_DIR="/home/alastair/Documents"
SERVANT_DIR="/home/alastair/03_July_Old_Files"

# Backup directory where the duplicates will be moved before deletion
BACKUP_DIR="/home/alastair/Temp_dupes"

# First, we run fdupes to find duplicate files between A and B
# The -r flag specifies that it should recurse into subdirectories
# The -N flag ensures that the newest file in each set of duplicates is preserved (optional)
DUPLICATE_FILES=$(fdupes -r "$MASTER_DIR" "$SERVANT_DIR")

# Create the backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"

# Move duplicate files to the backup directory
echo "Moving duplicate files to the backup directory..."
while IFS= read -r -d '' duplicate_file; do
    mv -- "$duplicate_file" "$BACKUP_DIR"
done < <(printf '%s\0' "$DUPLICATE_FILES")

echo "Duplicates moved to the backup directory: $BACKUP_DIR"

# Now, you can manually review the duplicates in the backup directory and ensure they are safe to delete.

# After reviewing, you can choose to delete the duplicates from the servant directory (B) if you're satisfied.
# Uncomment the following lines to delete the duplicates:

# echo "Deleting duplicates from $SERVANT_DIR..."
# fdupes -dN "$SERVANT_DIR"

# Alternatively, if you want to delete the duplicates individually, you can do it like this:
# for duplicate_file in "$BACKUP_DIR/Temp_dupes"/*; do
#     rm "$duplicate_file"
# done

echo "Review the duplicates in the backup directory before proceeding with deletion."

This has been commented by chatGPT and I have removed the -N option in fdupes because I do not want the date to be used. The result I get is this:-

alastair@HP-Z640-1:~> ./delete_duplicates_with_backup.sh
Moving duplicate files to the backup directory...
mv: cannot stat '/home/alastair/03_July_Old_Files/Documents/Packed_Food_Labels/Mains_Chilled_or_Frozen/Vegetable Tajine with Couscous'$'\n''(GF,V).odt'$'\n''/home/alastair/Documents/Packed_Food_Labels/Mains_Chilled_or_Frozen/Vegetable Tajine with Couscous'$'\n''(GF,V).odt'$'\n\n''/home/alastair/03_July_Old_Files/Documents/Packed_Food_Labels/Mains_Chilled_or_Frozen/Tomato & Green Bean Breedie'$'\n''(GF, V).odt'$'\n''/home/alastair/Documents/Packed_Food_Labels/Mains_Chilled_or_Frozen/Tomato & Green Bean Breedie'$'\n''(GF, V).odt': No such file or directory
Duplicates moved to the backup directory: /home/alastair/Temp_dupes
Review the duplicates in the backup directory before proceeding with deletion.
alastair@HP-Z640-1:~> 

Temp_dupes is created but the directory is empty and I have the errors shown. The problem may be the result of the files having too many characters or file names with spaces but it doesn’t work

Several other suggestions were tried (more than 18) but I ended up going round in circles. I did see however that when I has the second and subsequent suggested solutions I received the error message from Kate mentioned above. Here is another suggested solution:-

#!/bin/bash

# Replace 'path/to/master/directory/A' and 'path/to/servant/directory/B' with your actual directory paths
MASTER_DIR=/home/alastair/Documents
SERVANT_DIR=/home/alastair/03_July_Old_Files

# Backup directory where the duplicates will be moved before deletion
BACKUP_DIR=/home/alastair/Temp_dupes

# First, we run fdupes to find duplicate files between A and B
# The -r flag specifies that it should recurse into subdirectories
# The -N flag ensures that the newest file in each set of duplicates is preserved (optional)
DUPLICATE_FILES=$(fdupes -r -N "$MASTER_DIR" "$SERVANT_DIR")

# Create the backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"

# Move duplicate files to the backup directory using cpio
echo "Moving duplicate files to the backup directory..."
while IFS= read -r duplicate_file; do
    echo "$duplicate_file" | cpio -pd "$BACKUP_DIR"
done <<< "$DUPLICATE_FILES"

echo "Duplicates moved to the backup directory: $BACKUP_DIR"

# Now, you can manually review the duplicates in the backup directory and ensure they are safe to delete.

# After reviewing, you can choose to delete the duplicates from the servant directory (B) if you're satisfied.
# Uncomment the following lines to delete the duplicates:

# echo "Deleting duplicates from $SERVANT_DIR..."
# fdupes -dN "$SERVANT_DIR"

# Alternatively, if you want to delete the duplicates individually, you can do it like this:
# for duplicate_file in "$BACKUP_DIR"/*; do
#     rm "$duplicate_file"
# done

echo "Review the duplicates in the backup directory before proceeding with deletion."

And this gives me:-

[14:50:32  LSP Client Warning] Failed to find server binary: bash-language-server
Please check your PATH for the binary
See also https://github.com/bash-lsp/bash-language-server for installation or details

But when I check my system I cannot identify what provided bash-language-server.
I would appreciate a bit of guidance from a pro please.

What is this?

I doubt, but could be wrong, that your script “gives this”.

@Budgie2 maybe the jdupes package may work better… https://github.com/jbruchon/jdupes zypper in jdupes

Hi Malcolm,
OK will try but I think it is my script rather than the app which is at fault.

Of course you are right, this was not the output but an error reported in Dolphin. Now I have clarified have you any thoughts on what is wrong with the script?

Confusing. Are you now mixing two requests? I am insure about your peoblem description. Remind that a problem description has three parts:

  • What did you do
  • What happened
  • What did you expect to happen.

This looks over-complicated to me. And I wonder what IFS= does (and more).

That is the problem with these things. The syntax is OK, thus the script does what it is told to do. But it is of course a riddle what your idea is what it should do.

@hcvv IFS is a special bash variable for word boundaries…

Which might be the cause of the error message from Kate. Trouble is I am not sure what to install to solve this and of course have no idea if script works.

I agree overly complicated but when I was at the beginning and working with simple scripts I bumped into the file name limit and spaces in filenames and than I confess I tried chatGPT to get help with my script.
This is what took me down the rabbit hole.

I know that. I did not ask for an explanation of what IFS is, I asked what he thinks the effect of IFS= is.

@Budgie2

Can you please leave out all the small talking about chatGPT and stay tuned to the problem?

It seems that you want to do something with the standardout of fdupes -r "$MASTER_DIR" "$SERVANT_DIR". Please show a few of those line and tell what you want to do with them. Else it is impossible for others to check if what you wrote will do what you want.

What is the talking about Kate? Can you please stay tuned to one problem. I think I detected at least three you are mentioning:

  1. the programming problem with bash
  2. something about Dolphin
  3. and now something about Kate.

Let us dedicate this topic to #1 please. And when you want to multitask yourself, then start new topic on the other two.

The second example from your comment works here. I only changed the MASTER_DIR, SERVANT_DIR and BACKUP_DIR to fit my test directories.

So the question is, where you get the following output from. Kate is nowhere involved in executing the shell script. You supressed the command which leads to this message…

Btw, the shell script has some backdrafts. If you give a wrong (non existing) file path for SERVANT_DIR, it will copy the complete content of MASTER_DIR into BACKUP_DIR.

Test scenary that works:

MASTER_DIR

ich@laptop:~> ls /home/ich/test1 
a 1.txt  a1.txt  a 2.txt  a2.txt
ich@laptop:~> 

SERVANT_DIR

ich@laptop:~> ls /home/ich/test2
a 1.txt  a1.txt  a 2.txt  a2.txt
ich@laptop:~> 
ich@laptop:~> cat dupes.sh
#!/bin/bash

# Replace 'path/to/master/directory/A' and 'path/to/servant/directory/B' with your actual directory paths
MASTER_DIR=/home/ich/test1
SERVANT_DIR=/home/ich/test2

# Backup directory where the duplicates will be moved before deletion
BACKUP_DIR=/home/ich/back

# First, we run fdupes to find duplicate files between A and B
# The -r flag specifies that it should recurse into subdirectories
# The -N flag ensures that the newest file in each set of duplicates is preserved (optional)
DUPLICATE_FILES=$(fdupes -r -N "$MASTER_DIR" "$SERVANT_DIR")

# Create the backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"

# Move duplicate files to the backup directory using cpio
echo "Moving duplicate files to the backup directory..."
while IFS= read -r duplicate_file; do
    echo "$duplicate_file" | cpio -pd "$BACKUP_DIR"
done <<< "$DUPLICATE_FILES"

echo "Duplicates moved to the backup directory: $BACKUP_DIR"

# Now, you can manually review the duplicates in the backup directory and ensure they are safe to delete.

# After reviewing, you can choose to delete the duplicates from the servant directory (B) if you're satisfied.
# Uncomment the following lines to delete the duplicates:

# echo "Deleting duplicates from $SERVANT_DIR..."
# fdupes -dN "$SERVANT_DIR"

# Alternatively, if you want to delete the duplicates individually, you can do it like this:
# for duplicate_file in "$BACKUP_DIR"/*; do
#     rm "$duplicate_file"
# done

echo "Review the duplicates in the backup directory before proceeding with deletion."
ich@laptop:~>
ich@laptop:~> ./dupes.sh
Moving duplicate files to the backup directory...
1 Block
1 Block
1 Block
1 Block
1 Block
1 Block
1 Block
1 Block
Duplicates moved to the backup directory: /home/ich/back
Review the duplicates in the backup directory before proceeding with deletion.
ich@laptop:~> 

Some additional backdrafts of the script.

After you have uncommented # fdupes -dN "$SERVANT_DIR" you need to manually delete the contenet of the BACKUP_DIR

And it is always one file in the SERVANT_DIR left (a duplicate) after the shell script should have deleted them all…

The simple story is that I am using guis. I find, list and rename the script files in Dolphin, use Kate to write and edit the bash scripts and and run the scripts from the console.
The error I posted concerning IFS appeared in Kate when I was using it to edit the scripts.

I think you have exposed the root of my problem. The second part of my script was to avoid immediate deletion until I was sure but I shall now concentrate on dupes part and the backdrafts. I had tried to consider long file names and names with spaces but empty directories are a very likely culprit even when I have the basic script right.

I have to work on other matters ie. Photo tagging etc for the business so will return to this and check the actual Master and Servant directories first and when I have time. Meanwhile many thanks once more.