rodee
rodee

Reputation: 3151

Find files in different directories and operate on the filenames

$ ls /tmp/foo/
file1.txt  file2.txt
$ ls /tmp/bar/
file20.txt
$ ls /tmp/foo/file*.txt | grep -o -E '[0-9]+'  | sort -n | paste -s -d,
1,2

How to fetch the number in the filename from both the directories? in the above example, I need to get 1,2,20, its in bash shell.

UPDATE:

$ ls /tmp/foo/file*.txt /tmp/bar/file*.txt /tmp/jaz99/file*.txt /tmp/nah/file*.txt | grep -o -E '[0-9]+'  | sort -n | paste -s -d,
ls: cannot access /tmp/nah/file*.txt: No such file or directory
1,2,20,30,99

in this case, it should not print 99 (as its not matched by *), and should not print the error if file not found.

Upvotes: 2

Views: 87

Answers (2)

ghoti
ghoti

Reputation: 46826

Here's my take on this. Use arrays. No need to use external tools like sed or awk or find.

#!/usr/bin/env bash

declare -a a=()

for f in /tmp/{foo,bar,nah}/file*.txt; do
  [[ $f =~ .*file([0-9]+).* ]]
  a+=( ${BASH_REMATCH[1]} )
done

IFS=,
echo "${a[*]}"

The [[...]] expression populates the $BASH_REMATCH array with regex components. You can use that to extract the numbers and place them in a new temporary array, which you can express with comma separators using $IFS.

Results:

$ mkdir /tmp/foo /tmp/bar
$ touch /tmp/foo/file{1,2}.txt /tmp/bar/file20.txt
$ ./doit
1,2,20

Upvotes: 0

anubhava
anubhava

Reputation: 784928

You can get this done using a loop with output of find:

s=

# run a loop using find command in a process substitution
while IFS= read -d '' -r file; do
   file="${file##*/}"      # strip down all directory paths
   s+="${file//[!0-9]/},"  # remove all non-numeric characters and append comma
done < <(find /tmp/{foo,bar,nah,jaz99} -name '*.txt' -print0 2>/dev/null)

echo "${s%,}"              # remove last comma from string

Output

1,2,20,30

Upvotes: 2

Related Questions