How do you parse a filename in bash?

39,996

Solution 1

You can use the cut command to get at each of the 3 'fields', e.g.:

$ echo "system-source-yyyymmdd.dat" | cut -d'-' -f2
source

"-d" specifies the delimiter, "-f" specifies the number of the field you require

Solution 2

A nice and elegant (in my mind :-) using only built-ins is to put it into an array

var='system-source-yyyymmdd.dat'
parts=(${var//-/ })

Then, you can find the parts in the array...

echo ${parts[0]}  ==> system
echo ${parts[1]}  ==> source
echo ${parts[2]}  ==> yyyymmdd.dat

Caveat: this will not work if the filename contains "strange" characters such as space, or, heaven forbids, quotes, backquotes...

Solution 3

Depending on your needs, awk is more flexible than cut. A first teaser:

# echo "system-source-yyyymmdd.dat" \
    |awk -F- '{printf "System: %s\nSource: %s\nYear: %s\nMonth: %s\nDay: %s\n",
              $1,$2,substr($3,1,4),substr($3,5,2),substr($3,7,2)}'
System: system
Source: source
Year: yyyy
Month: mm
Day: dd

Problem is that describing awk as 'more flexible' is certainly like calling the iPhone an enhanced cell phone ;-)

Solution 4

Use the cut command.

e.g.

echo "system-source-yyyymmdd.dat" | cut -f1 -d'-'

will extract the first bit.

Change the value of the -f parameter to get the appropriate parts.

Here's a guide on the Cut command.

Solution 5

Another method is to use the shell's internal parsing tools, which avoids the cost of creating child processes:

oIFS=$IFS
IFS=-
file="system-source-yyyymmdd.dat"
set $file
IFS=$oIFS
echo "Source is $2"
Share:
39,996
Nick Pierpoint
Author by

Nick Pierpoint

I live in the UK.

Updated on July 07, 2020

Comments

  • Nick Pierpoint
    Nick Pierpoint almost 4 years

    I have a filename in a format like:

    system-source-yyyymmdd.dat

    I'd like to be able to parse out the different bits of the filename using the "-" as a delimiter.