mac389
mac389

Reputation: 3133

Extract part of a filename shell script

In bash I would like to extract part of many filenames and save that output to another file.

The files are formatted as coffee_{SOME NUMBERS I WANT}.freqdist.

#!/bin/sh
for f in $(find . -name 'coffee*.freqdist)

That code will find all the coffee_{SOME NUMBERS I WANT}.freqdist file. Now, how do I make an array containing just {SOME NUMBERS I WANT} and write that to file?

I know that to write to file one would end the line with the following.

  > log.txt

I'm missing the middle part though of how to filter the list of filenames.

Upvotes: 10

Views: 28295

Answers (4)

Abhishek Ghosh
Abhishek Ghosh

Reputation: 193

Expanding on this topic, let's say the filename has this format :

first_second_third_requiredText_fourth_fifth_sixth

To get only requiredText use the following :

filename=first_second_third_requiredText_fourth_fifth_sixth
removed_first_part=${filename#*_*_*_}
finalText=${removed_first_part%_*_*_*}

'#' starts from the beginning of the string, '%' from the end, '*' for any number of characters. This also works for full paths.

Upvotes: 0

James Waldby - jwpat7
James Waldby - jwpat7

Reputation: 8711

The previous answers have indicated some necessary techniques. This answer organizes the pipeline in a simple way that might apply to other jobs as well. (If your sed doesn't support ‘;’ as a separator, replace ‘;’ with ‘|sed’.)

$ ls */c*; ls c*
 fee/coffee_2343.freqdist
 coffee_18z8.x.freqdist  coffee_512.freqdist  coffee_707.freqdist
$ find . -name 'coffee*.freqdist' | sed 's/.*coffee_//; s/[.].*//' > outfile
$ cat outfile 
 512
 18z8
 2343
 707

Upvotes: 1

dogbane
dogbane

Reputation: 274838

You can do it natively in bash as follows:

filename=coffee_1234.freqdist
tmp=${filename#*_}
num=${tmp%.*}
echo "$num"

This is a pure bash solution. No external commands (like sed) are involved, so this is faster.

Append these numbers to a file using:

echo "$num" >> file

(You will need to delete/clear the file before you start your loop.)

Upvotes: 17

Guru
Guru

Reputation: 17054

If the intention is just to write the numbers to a file, you do not need find command:

ls coffee*.freqdist
coffee112.freqdist  coffee12.freqdist  coffee234.freqdist

The below should do it which can then be re-directed to a file:

$ ls coffee*.freqdist | sed 's/coffee\(.*\)\.freqdist/\1/'
112
12
234

Guru.

Upvotes: 7

Related Questions