dominique120
dominique120

Reputation: 1302

Extracting a numbers from filenames

I have a bunch of files that all have a name and a serial number and an extension. I want to extract this serial number and extension. They look like this:

photo-123.jpg
photo-456.png
photo-789.bmp

etc.

I want to run a bash script to extract these serial numbers and place them in a file in this way:

123
456
789

etc.

Note that not all the photos have the same extension (bmp, png, jpg) but they all start with photo-.

Upvotes: 2

Views: 248

Answers (5)

Juan Aguilera
Juan Aguilera

Reputation: 19

Or maybe with two consecutive awk calls:

ls -1 | awk -F- '{print $2}' | awk -F. '{print $1}'

Upvotes: 0

Satyaanveshi
Satyaanveshi

Reputation: 169

How about

ls -l | awk {'print $9'} | grep -o -E '[0-9]*'

in the directory where the files reside?

Upvotes: -1

jaypal singh
jaypal singh

Reputation: 77095

You can use parameter substitution:

$ ls
photo-123.jpg  photo-456.png  photo-7832525239.bmp  photo-789.bmp

$ for file in *; do 
    [[ -f "$file" ]] || continue
    [[ $file == "num.log" ]] && continue
    file=${file%.*} && echo "${file#*-}" 
done > num.log

$ ls
num.log  photo-123.jpg  photo-456.png  photo-7832525239.bmp  photo-789.bmp

$ cat num.log 
123
456
7832525239
789

${parameter#word} removes the shortest match from the start and ${parameter##word} removes the longest match from the start. ${parameter%word} on the contrary will remove shortest match from the end and ${parameter%%word} will remove longest match from the end.

Alternatively, you can read about nullglob instead of checking for existence of file in event there are no files in the directory. (Thanks Adrian Frühwirth for great feedback)

Upvotes: 4

dannysauer
dannysauer

Reputation: 3867

Assuming you just want to keep all of the numbers and you're using bash, here are a couple of things which you may find useful:

danny@machine:~$ file=abc123def.jpg
danny@machine:~$ echo ${file//[^0123456789]/}
123
danny@machine:~$ echo ${file##*.}
jpg
danny@machine:~$ echo ${file//[^0123456789]/}.${file##*.}
123.jpg

You should be able to write your script based on that. Or, just remove the leading "photo-" from $name by using

newname=$(name#photo-}

Those and several others are explained in the man page's Parameter Expansion section.

Upvotes: 2

anubhava
anubhava

Reputation: 785108

Using BASH regex:

f='photo-123.jpg'
[[ "$f" =~ -([0-9]+)\. ]] && echo "${BASH_REMATCH[1]}"
123

To run it against all the matching files:

for f in *-[0-9]*.*; do
   [[ "$f" =~ -([0-9]+)\. ]] && echo "${BASH_REMATCH[1]}"
done

Upvotes: 2

Related Questions