> For the complete documentation index, see [llms.txt](https://morgan-bin-bash.gitbook.io/bash-scripting/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://morgan-bin-bash.gitbook.io/bash-scripting/extract-filename-without-extension-from-full-path-in-bash.md).

# Extract Filename without Extension from Full Path in Bash

### 1. Introduction

In this tutorial, we delve into the world of bash scripting and explore techniques to extract filenames from file paths while trimming the extension. We cover essential tools like basename, parameter expansion, cut, awk, and sed, highlighting their unique features and applications. By mastering these methods, you'll gain the ability to efficiently manipulate filenames in bash scripts, enabling tasks such as renaming and copying files with ease.

### 2. Using basename

As we gathered, the sole role of the bash command is to give us the file name from the path. But if the file name has an extension, we get that too. We can still use the command to get rid of the [extension](https://linuxopsys.com/topics/extract-extension-from-file-path-in-bash) or any suffix. This ensures we end up a clean output of just the name of the file.

Example:

```
basename /home/ubuntu/sample.txt .txt
basename -s .txt /home/ubuntu/sample.txt
```

<figure><img src="https://linuxopsys.com/wp-content/uploads/2023/05/bash-extract-file-name-wo-ext-232023-01.png" alt="Command output: &#x27;sample&#x27; - basename /home/ubuntu/sample.txt .txt" height="139" width="710"><figcaption></figcaption></figure>

We are aware the command accepts two syntaxes. They are just a different way of writing. In the first one we have to provide the path and the extension we want to be trimmed from the final output. In the latter case, we have the -s option which accepts the extension we want to remove.&#x20;

In both cases, the [basename](https://linuxopsys.com/topics/bash-basename-command-with-examples) should produce the result "sample.txt". As we have provided the suffix, the output will be trimmed further by removing the .txt from the result. We will get the final output "sample". If we provide an imaginary suffix or one that is not at the end, the outcome remains the same. It will assume there was no suffix.

We can, with certain limitations, combine -s and -a flag to trim extensions from multiple inputs.

Example:

```
basename -as .txt /home/ubuntu/readmecopy.txt /home/ubuntu/readme.txt
basename -as .txt /home/ubuntu/readmecopy.txt /home/ubuntu/config.cfg
```

<figure><img src="https://linuxopsys.com/wp-content/uploads/2023/05/bash-extract-file-name-wo-ext-232023-02.png" alt="Output of basename command: removing &#x27;.txt&#x27; suffix from &#x27;/home/ubuntu/readmecopy.txt&#x27; and &#x27;/home/ubuntu/readme.txt&#x27;" height="207" width="710"><figcaption></figcaption></figure>

In the first case, we have asked the command to remove the .txt extension from multiple inputs. But there is a loophole. We cannot assign individual suffices. That won’t work. Our hand is forced as we can only provide one suffix to all the file paths.

If multiple files with different extensions exist, then it will trim the ones whose extensions match with the supplied. In our case, we get "sample" and "sample.cfg" as the eventual output. They will be separated by a line break.

### 3. Using parameter expansion

We saw how parameter expansions work above and how we can use it to extract the file name with the extension. But we might only be interested in the file name. We can still proceed with it.

Example:

```
filepath=/home/ubuntu/sample.txt
filename=$(basename $filepath)
echo ${filename%.*}
```

<figure><img src="https://linuxopsys.com/wp-content/uploads/2023/05/bash-extract-file-name-wo-ext-232023-03.png" alt="using parameter expansion - Extracting filename without extension" height="152" width="644"><figcaption></figcaption></figure>

The above example can be generalized as follows:

```
${variable%pattern}
```

This trims the shortest match from the end of the pattern. It displays whatever is after the pattern. The shortcoming again is that we need a variable because of the parameter expansion.

In our example, we have [extracted the filename from the file path](https://linuxopsys.com/topics/extract-filename-from-absolute-path-in-bash) using the basename command. Then we used the parameter expansion.

We have used the regex (\*) as the pattern. We have also added the dot (.) before the regular expression. This dot represents the beginning of the extension.

Bash will look for all the characters from the last dot and trim it. Hence, we will get the characters before the final dot. This gives us just the name of the file.

### 4. Using powerful Bash tools

We talked about utilizing the powerful built-in tools to fetch the file name. They may appear complex at first. Let us understand them one by one and how we can integrate the regular expressions.

#### 4.1 Using cut

Example:

```
path="/home/ubuntu/contents.tar.gz"
echo "$path" | cut -f 1 -d '.' | tr '/' '\n' | tail -1
```

<figure><img src="https://linuxopsys.com/wp-content/uploads/2023/05/bash-extract-file-name-wo-ext-232023-04.png" alt="cut command -  Extracting filename without extension" height="120" width="710"><figcaption></figcaption></figure>

Cut is a very straightforward tool. And it comes in handy in our case to extract the file name. We have combined it with some of the readily available tools- tr and tail.

In our example, we pipe the result of the echo command so that Bash can send it as an input to the [cut](https://linuxopsys.com/topics/cut-command-in-linux) command. The cut command uses the delimiter (-d) as the dot (.) for extension. This [splits the string](https://linuxopsys.com/topics/bash-split-string-by-delimiter) into two parts- one before the dot and the other after.

The -f 1 option ensures that Bash opts for the former. This is then sent to the [tr](https://linuxopsys.com/topics/tr-command-in-linux) command which substitutes the path separator with line breaks. From this we have to pick the last line. Tail -1 does that job for us.

To sum up our example:

* **Cut** makes /home/ubuntu/contents.tar.gz become /home/ubuntu/contents
* **Tr** breaks /home/ubuntu/contents into 3 different lines\
  home\
  ubuntu\
  Contents
* **Tail** prints contents&#x20;

#### 4.2 Using awk

Example:

```
path="/home/ubuntu/sample.txt"
echo "$path" | awk -F '/' '{sub(/[.][^.]*/,"",$NF); print $NF}'
```

<figure><img src="https://linuxopsys.com/wp-content/uploads/2023/05/bash-extract-file-name-wo-ext-232023-05.png" alt="using awk - Extracting filename without extension" height="121" width="710"><figcaption></figcaption></figure>

In this example, we have taken a variable to hold the entire file path. We are free to supply that string directly to the echo command. We pipe the result of this echo command so that Bash can send it as an input to the awk command.

The -F option available with the awk command acts as the field separator. We have built the regular expression for the awk statement in such a way that the string dissociates into two halves from the final slash (/).

We then pick the last half of the field using $NF. This will contain the filename without the path information. Next, we call the available function with awk- sub(). This clears the file extension and prints the result as the filename.

#### 4.3 Using sed

Example:

```
path="/home/ubuntu/sample.txt"
echo $path | sed 's|.*/||; s|[.][^.]*$||'
```

<figure><img src="https://linuxopsys.com/wp-content/uploads/2023/05/bash-extract-file-name-wo-ext-232023-06.png" alt="usind sed - Extracting filename without extension" height="122" width="710"><figcaption></figcaption></figure>

In this example as well, we store the entire file path in a variable. We can also feed the string directly to the echo command. We pipe the result of this echo command, which becomes the input to the [sed command](https://linuxopsys.com/topics/sed-command-in-linux).

After that it is just a case of providing the right regular expression to the command. The s option with the flag is used to tell Bash that sed wants to carry out substitution. We have taken the symbol | to act as a separator for the sed syntax. This character may be uniformly replaced by any other single character within any given s command.

We have used two regular expressions here:

**s|.\*/||** : This expression ends up removing everything till the last slash. This is the parent directory of the file.

**s|\[.]\[^.]\*$||** – This regular expression trims everything after the last dot. This gets rid of the file’s extension.

We can notice that the core regular expression /\[^.]\*$ in the above awk command and here has remained the same.&#x20;

### 5. Example Script

As we have learned different ways of fetching the name of the file, we can look at an example that prompts the user to provide the complete path of the file. The script checks the existence of the file. It then asks the user to provide the extension so that the script can create a copy of the same file with a different extension.

| `#!/bin/bash` `read` `-p "Enter the filename with it's complete path: "` `fpath`  `if` `[ ! -f "$fpath"` `]then    echo` `"Invalid file. Please check the input."else    read` `-p "Enter the new extension you want: "` ``ext    fname=`basename`` ``$fpath`    fname=`echo`` ``${fname%.*}`    dname=`dirname`` ``$fpath`    cp`` `$fpath ${dname}/${fname}.${ext}`  `fi` |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

<figure><img src="https://linuxopsys.com/wp-content/uploads/2023/05/bash-extract-file-name-wo-ext-232023-07.png" alt="Bash script: Prompting user to enter a file path, changing extension, and copying the file" height="283" width="710"><figcaption></figcaption></figure>

1\. The script starts by asking the user to enter the filename with its complete path using the [read command](https://linuxopsys.com/topics/bash-read-examples). The entered value is stored in the fpath variable.

2\. The script checks if the file specified by fpath does not exist using the -f test condition. If the file doesn't exist, it prints "Invalid file. Please check the input."

3\. If the file exists, the script prompts the user to enter the new extension. This response is stored in the ext variable.

4\. The script pulls out the name of the file with the extension using the basename command. Using [backticks](https://linuxopsys.com/topics/bash-backticks-vs-dollar-parentheses) technique, it stores the response of the command in the variable fname.

5\. It then uses the parameter expansion to get rid of the extension. This gives just the filename and the script overwrites the variable fname with this value.&#x20;

6\. Similarly, the script utilizes the dirname command to get the directory path from the user input present in fpath. The variable dname stores the output of the dirname command.\
\
7\. Finally, the script copies the file from the location in fpath to the destination ${dname}/${fname}/${ext}.

8\. This ensures that the file is copied in the same location with the same name and with a user-provided extension.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://morgan-bin-bash.gitbook.io/bash-scripting/extract-filename-without-extension-from-full-path-in-bash.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
