2
$\begingroup$

I need to generate a list of unique file names without their extensions or using the shell script command "find"

Say I have a list such as:

file2022_col.R1.twx.gz
file2022_col.R2.twx.gz
file2022_col.bwa.bam
file2332_col.R1.twx.gz
file2332_col.bwa.bam
file3442_col.bwa.bam.bai

I want a list of unique file names such as:

file2022_col
file2332_col
file3442_col

I'm trying to use find -type f -name but I'm not sure how to construct the option to restrict the find command.

$\endgroup$

3 Answers 3

2
$\begingroup$

It is simpler to use cut command to remove filename extensions:

ls -1 | cut -d '.' -f1 | sort | uniq
$\endgroup$
2
  • $\begingroup$ This seems nice and clean, but it will also pick up any directory names. I only want to extract from file names. $\endgroup$
    – Lou_A
    Commented Jul 19, 2022 at 19:05
  • $\begingroup$ ls -1 -p | grep -v '/' could filter directories. The -p flag appends / indicator to directories. Then the -v flag only matches files. $\endgroup$ Commented Jul 21, 2022 at 7:20
1
$\begingroup$
ls | perl -p -n -e  's/(.*)(\..*){1,3}$/$1/' | uniq

or

find . -name "file*" | perl -p -n -e  's/(.*)(\..*){1,3}$/$1/' | uniq

find per se is a really powerful command, but its a while since I've used it full functionality.

$\endgroup$
2
  • 2
    $\begingroup$ Thanks, M__. I'll test it. I notice you call perl. I'm hoping to find a way to run it entirely in shell, but this could work too. $\endgroup$
    – Lou_A
    Commented Jun 2, 2022 at 14:29
  • $\begingroup$ Bash has a regex, so it can be rewritten, but dunno if it has the {1,3} syntax $\endgroup$
    – M__
    Commented Jun 2, 2022 at 18:13
1
$\begingroup$

Use find, remove all extensions with perl, and make unique with sort:

find . -type f -printf '%P\n' | perl -pe 's{[.].*}{}' | sort -u

The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-p : Loop over the input one line at a time, assigning it to $_ by default. Add print $_ after each loop iteration.

s{[.].*}{} : replace [.] (a literal dot), followed by .* (any character repeated 0 or more times) with en empty string.

SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches
perldoc perlre: Perl regular expressions (regexes)
perldoc perlre: Perl regular expressions (regexes): Quantifiers; Character Classes and other Special Escapes; Assertions; Capture groups
perldoc perlrequick: Perl regular expressions quick start

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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