0

I have a variable f in a bash script

f=/path/to/a/file.jpg

I'm using the variable as an input argument to a program that requires and input and an output path.

For example the program's usage would look like this

./myprogram -i inputFilePath -o outputFilePath

using my variable, I'm trying to maintain the same basename, change the extension, and put the output file into a sub directory. For example

./myprogram -i /path/to/a/file.jpg -o /path/to/a/new/file.tiff

I'm trying to do that by doing this

./myprogram -i "$f" -o "${f%.jpg}.tiff"

of course this keeps the basename, changes the extension, but doesn't put the file into the new subdirectory.

How can I modify f to to change /path/to/a/file.jpg into /path/to/a/new/file.tiff?

3
  • 1
    Your goal is unclear. If you want to completely change f, you'll have to reassign it, i.e., by f=/path/to/a/new/file.tiff. if you want to keep some part of f, there are ways just as dirname or basename or your method with parameter expansion. Commented Jun 13, 2018 at 18:37
  • my goal isn't to modify f persay but to use the path in f to specify the -o path/filename Commented Jun 13, 2018 at 18:38
  • 1
    $(dirname f) will give you the path of f. Commented Jun 13, 2018 at 18:39

3 Answers 3

2

Actually you can do this in several ways:

  1. Using sed as pointed out by @anubhava
  2. Using dirname and basename:

    ./myprogram -i "$f" -o "$(dirname -- "$f")/new/$(basename -- "$f" .jpg).tiff"
    
  3. Using only Bash:

    ./myprogram -i "$f" -o "${f%/*}/new/$(b=${f##*/}; echo -n ${b%.jpg}.tiff)"
    

Note that unlike the second solution (using dirname/basename) that is more robust, the third solution (in pure Bash) won't work if "$f" does not contain any slash:

$ dirname "file.jpg"
.
$ f="file.jpg"; echo "${f%/*}"
file.jpg
Sign up to request clarification or add additional context in comments.

Comments

1

You may use this sed:

s='/path/to/a/file.jpg'
sed -E 's~(.*/)([^.]+)\.jpg$~\1new/\2.tiff~' <<< "$s"

/path/to/a/new/file.tiff

Comments

1

If you're on a system that supports the basename and dirnamecommands you could use a simple wrapper function eg:

$ type newSubDir
newSubDir is a function
newSubDir ()
{
    oldPath=$(dirname "${1}");
    fileName=$(basename "${1}");
    newPath="${oldPath}/${2}/${fileName}";
    echo "${newPath}"
}

$ newSubDir /path/to/a/file.jpg new
/path/to/a/new/file.jpg

If your system doesn't have those, you can accomplish the same thing using string manipulation:

$ file="/path/to/a/file.jpg"

$ echo "${file%/*}"
/path/to/a

$ echo "${file##*/}"
file.jpg

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.