cybertextron
cybertextron

Reputation: 10981

parsing string in bash

I have a bunch of C++ files in a directory called src. I needed to find all the files that have *Test.cc, but without the .cc file type, so it would just be [filename]Test. I currently have:

  1 FILES=./src/*Test.cc
  2 
  3 for f in $FILES
  4     do
  5         echo "processing $f"
  6 done

so I only need the name of the file, without ./src/ and without .cc. For example, the above script would produce:

processing ./src/UtilTest.cc

And I only need UtilTest. How can I accomplish that?

Upvotes: 0

Views: 245

Answers (3)

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38042

Just to show you another option: for later versions of bash (not sure anymore which version), you can use arrays and string manipulation:

files=(.src/*Test.cc)      # create bash array (space-separated)

for f in ${files[@]##./}   # loop through array, stripping leading path 
do 
     echo ${f%%.*}         # f is now array element; strip its extension
done

Obviously, as in your own example, when the file name contains spaces or has multiple extentions (e.g., Your File Test.cc.hpp), there will be problems.

Anyway, this sidesteps the call to basename and does not require a temp file, as in the other two answers; the only downside is its limited portability due to bash version requirements.

Upvotes: 1

Edward Fitz Abucay
Edward Fitz Abucay

Reputation: 483

You can accomplish that with this one liner commands:

First is storing it in a file for reference:

find ./src/ -name *Test.cc | tee samp.txt

Then printing it or it depends on what you want do with the file:

cat samp.txt | while read i; do echo `basename $i .cc`; done;

Upvotes: 2

user1760725
user1760725

Reputation:

Inserting this line between your lines 4 and 5 will cause your bash snippet to produce the desired output:

f=$(basename $f .cc)

Upvotes: 3

Related Questions