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
    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. – don_crissti May 10 '17 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 – Sudoscience May 10 '17 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 – Sudoscience May 10 '17 at 19:28
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 {} \;
  • 1
    ${var//pattern/replacement} is a ksh/zsh/bash feature, not sh. – Stéphane Chazelas May 10 '17 at 20:15
  • ${1%%-*} may be problematic if the directory names contain dashes. – Stéphane Chazelas May 10 '17 at 20:19
  • They're using bash but you're calling sh -c. That should be bash -c. – Stéphane Chazelas May 10 '17 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 {} \;  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.