1

I have a script which at one point does the following:

for src in $(find -H "$ROOT_DIR" -maxdepth 5 -name '*.test' -not -path '*.git*')
  do
    fixed_filename=$(echo "$(basename "${src%.*}")" | sed 's/-test//')

Basically, I have files called thing-test.js.test

When looping through I'd like to end up with the filename being thing.js

Eventually then I'll create the full path to the file using path="$ROOT_DIR"/"$fixed_filename"

The above seems to work, but it's definitely not correct - I'm an avid user of shellcheck and it tells me there's a useless echo (I agree) and to attempt ${variable//search/replace} if possible.

Would appreciate some help on cleaning up the above.

Edit:

The basic gist of what I'm trying to do is:

I'm trying to recursively search through every file in a directory following a particular file name pattern e.g. file-test.js.test and inside of these files are placeholder variables e.g. REPLACEME I want to find all these files, and one-by-one replace REPLACEME with a user supplied string from a read call inside of the bash script, and while I'm there I'd like to change the filename to file.js e.g. remove -test and .test

3
  • 3
    You're doing this the wrong way. See the answers here Also, you don't need sed and basename for this job, shell parameter expansion alone can do it. Commented May 10, 2017 at 18:52
  • @don_crissti It's too much information for a title IMO, I couldn't think of a good title. I'm trying to recursively search through every file in a directory following a particular file name pattern e.g. file-test.js.test and inside of these files are placeholder variables e.g. REPLACEME I want to find all these files, and one-by-one replace REPLACEME with a user supplied string from a read call inside of the bash script, and while I'm there I'd like to change the filename to file.js e.g. remove -test and .test Commented May 10, 2017 at 19:22
  • I have edited my post now. For now, all of these files will follow the same pattern (filename-test.js.test) but I'm probably going to be extending the script to support other dash separations e.g. filename-X.js.test since some of those will be present too in the future but for now I was just concentrating on the originals Commented May 10, 2017 at 19:28

2 Answers 2

1

To rename e.g. stuff-X.js.test to stuff.js (without knowing the extension before .test) you would have to use several expressions to extract the needed parts e.g. split the path into head h=${path%/*} and tail t=${path##*/} then get string before the dash with ${t%%-*} and for the string in the middle get the name without extension e.g. noext=${t%.*} then from that extract what now is the new extension with ext=${noext##*.} so something like:

find . -name '*-*.test' -exec sh -c 'h=${1%/*}; t=${1##*/}; noext=${t%.*};\
ext=${noext##*.}; fixed=${h}/${t%%-*}.${ext}; echo mv "$1" "$fixed"' sh {} \;
3
  • 1
    ${var//pattern/replacement} is a ksh/zsh/bash feature, not sh. Commented May 10, 2017 at 20:15
  • ${1%%-*} may be problematic if the directory names contain dashes. Commented May 10, 2017 at 20:19
  • They're using bash but you're calling sh -c. That should be bash -c. Commented May 10, 2017 at 20:24
0

Use find command coupled with shell using -exec flag:

$ find -name "*.test" -exec sh -c 'echo "$(basename -s ".test" "$1")".js'  sh {} \;  
one.js
three.js
two.js

Note that basename -s ".test" "$1" removes the suffix, so you don't need to call sed in the first place.

If eventually you need to do something else with that "fixed filename", replace that echo with variable assignment and keep working within same sh command. Something like this:

$ find -name "*.test" -exec sh -c 'fixed_name=$(basename -s ".test" "$1").js; my_other_command "$fixed_name"'  sh {} \;  

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .