Alcott
Alcott

Reputation: 18615

extract numbers from file names

I got a lot of files whose names are like this:

tmp1.csv
tmp32.csv
tmp9.csv
tmp76.csv
...

They are in the same dir, and I want to extract the numbers in the file name. How can I do that in bash?

PS

I tried grep, but can't make it. Also I tried ${filename##[a-z]}. Are they the right way to go?

Upvotes: 4

Views: 3589

Answers (5)

Tim Pote
Tim Pote

Reputation: 28059

find . -maxdepth 1 -type f -name 'tmp[0-9]*.csv' | sed 's/tmp\([0-9]\+\).csv/\1/'

Upvotes: 1

Facundo Casco
Facundo Casco

Reputation: 10605

ls |grep -o "[0-9]\+"

Example:

$ ls *.csv
3tmp44.csv  newdata_write.csv  tmp1.csv  tmp2.csv

$ ls *.csv |grep -o "[0-9]\+"
3
44
1
2

Edit:

From grep man page:

Basic vs Extended Regular Expressions

   In basic regular expressions the meta-characters ?, +, {, |, (, and )  lose  their  special  meaning;  instead  use  the  backslashed
   versions \?, \+, \{, \|, \(, and \).

That is why you need to use \+

Upvotes: 4

Charles Duffy
Charles Duffy

Reputation: 295904

Easy peasy, using no subprocesses or other tools external to bash itself:

for f in *[0-9]*; do
  if [[ $f =~ [0-9]+ ]] ; then
    echo "$BASH_REMATCH"
  fi
done

Upvotes: 3

unwind
unwind

Reputation: 400129

I would probably use a couple of invocations of cut:

$ ls -1 *.csv | cut -dp -f 2 | cut -d. -f1

This pipe does:

  1. List all files matching the *.csv pattern, one per line
  2. Use the letter 'p' as the delimiter, and cut out the second field on each line. This transforms e.g. tmp4711.csv into 4711.csv.
  3. Use the letter '.' as the delimiter, and cut out the first field on each line. This transforms 4711.csv into just 4711, leaving the number isolated and we're done.

Upvotes: 3

codaddict
codaddict

Reputation: 455440

for f in *.csv; do echo $f | egrep -o "[0-9]+" ; done

If you have other csv file with digits in their filenames use:

for f in *.csv; do echo $f | sed -re 's/^tmp([0-9]+)\.csv$/\1/' ; done

Upvotes: 3

Related Questions