LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 05-21-2022, 01:20 PM   #1
Faki
Member
 
Registered: Oct 2021
Posts: 574

Rep: Reputation: Disabled
Directories and files without duplicates


I would be pass directory names or file names as arguments to a bash function. But want to do a check existence and remove duplicates before storing in array fdir. Currently I can handle directory names, but want to extend the code to include and check file names in addition to directory names.

The command [[ ! -d $dpa ]] && continue fails to take account of files.

Code:
declare -A tag
for dpa in "$@"; do
  [[ ! -d $dpa ]] && continue
  [[ ${tag[comint:$dpa]} ]] && continue
  fdir+=("$dpa")
  tag[comint:$dpa]=1
done

Last edited by Faki; 05-21-2022 at 01:59 PM.
 
Old 05-21-2022, 01:48 PM   #2
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,146
Blog Entries: 6

Rep: Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833
"$@" will expand to "$1" "$2"...
If there are no positional parameters, "$@" expands to nothing.

So, you are running that with args? Need some info.

I ran that. Doesn't do anything except echo the dirs that you enter as args.

test.sh
Code:
#!/usr/bin/bash

declare -A tag

for dpa in "$@"; do
  [[ ! -d $dpa ]] && continue
  [[ ${tag[comint:$dpa]} ]] && continue
  fdir+=("$dpa")
  tag[comint:$dpa]=1
done

echo "${fdir[@]}"
echo "${tag[@]}"
You want to tell what you are trying to achieve, or just ignore the forum and keep on going?
 
Old 05-21-2022, 01:53 PM   #3
Faki
Member
 
Registered: Oct 2021
Posts: 574

Original Poster
Rep: Reputation: Disabled
Yes, I would pass directory names or file names as arguments to a bash function. But want to do a check existence and remove duplicates before storing in array fdir.

Last edited by Faki; 05-21-2022 at 01:56 PM.
 
Old 05-21-2022, 01:56 PM   #4
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,146
Blog Entries: 6

Rep: Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833
If you want to find duplicate file names in subdirectories
Code:
find . -maxdepth 2 -printf "%f\n" | sort -f | uniq -di
 
Old 05-21-2022, 02:10 PM   #5
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,945

Rep: Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325
you need to use associative array if you want to catch duplicated arguments.
you can have not only -d but -f too to check, see man test (for example)
 
Old 05-21-2022, 02:11 PM   #6
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
Test for existence:
Code:
[[ ! -e $dpa ]] && continue
Explicitly test for directory or file (and not a special file):
Code:
[[ -d $dpa ]] || [[ -f $dpa ]] || continue
--
The following is correct - it tests the value; not existing members are substituted by an empty value (empty string).
Code:
[[ ${tag[comint:$dpa]} ]] && continue
More efficient is to directly test for existence:
Code:
[[ ${tag[comint:$dpa]+X} ]] && continue
Then the defined members may have an empty value:
Code:
tag[comint:$dpa]=
 
Old 05-21-2022, 02:35 PM   #7
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,146
Blog Entries: 6

Rep: Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833Reputation: 1833
This will spit out duplicate files in tree. Might do it better.
Example:
Code:
for f in *; do
    find . -maxdepth 2 -iname "$f" | wc -l | while read count; do
        [ $count -gt 1 ] && find -iname "$f"
    done
done
 
Old 05-22-2022, 06:09 AM   #8
Faki
Member
 
Registered: Oct 2021
Posts: 574

Original Poster
Rep: Reputation: Disabled
Having defined members with empty values does not seem relevant. Because arguments are being passed, composed of directories and files (with possibility of user-errors).

I do not quite understand what `[[ ${tag[comint:$dpa]+X} ]] && continue` does. Would I still keep `tag[comint:$dpa]=1`? Some examples would help me understand your plan.

Last edited by Faki; 05-22-2022 at 06:25 AM.
 
Old 05-22-2022, 07:13 AM   #9
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
${tag[comint:$dpa]+X}
or generally
${var+string}
If $var exists then substitute "string".
If it does not exist then substitute nothing (empty string "").

[[ ]] without a further operator is true for a non-empty string.

The && runs the following command if the previous result was true. You can as well do
Code:
if [[ ${tag[comint:$dpa]+X} ]]; then continue; fi

Last edited by MadeInGermany; 05-22-2022 at 07:14 AM.
 
Old 05-22-2022, 09:15 AM   #10
Faki
Member
 
Registered: Oct 2021
Posts: 574

Original Poster
Rep: Reputation: Disabled
I understand. This means that I should have

Code:
[[ ${tag[comint:$dpa]+X} ]] && continue
followed by

Code:
tag[comint:$fda]=1
How is your solution an improvement over

Code:
[[ ${tag[comint:$fda]} ]] && continue
 
Old 05-22-2022, 09:49 AM   #11
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
Not much.
It takes a few CPU cycles less, and allows
tag[comint:$fda]= that is a few bytes less.
 
  


Reply

Tags
bash



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to Sync and omit duplicates between directories leoio2 Linux - General 5 03-31-2020 04:36 AM
Look for duplicates in folder tree A and folder tree B, then delete the duplicates only from A. grumpyskeptic Linux - Software 7 10-27-2018 10:23 PM
Delete duplicates without using sort -u? MikeyCarter Linux - Software 8 10-23-2012 03:19 AM
Chemistry problem: Identify duplicates and non-duplicates within TWO sdf files robertselwyne Programming 5 12-09-2011 06:20 AM
Merging files and removing near-duplicates TheBigH Linux - Newbie 3 12-02-2009 04:24 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 03:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration