basename

Does basename work in shell scripts, if so, what is the proper syntax?

When i enter: neme=basename x.x .x
I get: If ‘x.x’ is not a typo you can use command-not-found to lookup the package that contains it, like this:
cnf x.x

It is a executable file

henk@boven:~> type basename
basename is /usr/bin/basename
henk@boven:~>

and the documentataion is of course in

man basename

And you can of course call it from a shell:

henk@boven:~> basename /usr/bin/basename
basename
henk@boven:~>

Well, of course.

The command you used says to set “neme=basename” in the environment, and then run the command

x.x .x

And that seems to have done what it should.

Try:

neme=`basename x.x .x`

That probably does what you want.

Maybe you’d better describe in detail what you want to achieve using the command.

What I am trying to do is strip directory and extension names in a script file. Passing the filename in a variable.
Here is the actual code:
cd $1
mkdir aif
for file in *.aif do
#echo $file
name=basename${file}.aif
#echo $name
wave=${name}.wav
#echo $wave
sox $file $wave
mv $file aif
done

Change this line:

name=basename${file}.aif

to

name=`basename ${file} .aif`

The back quotes tell the shell to run the quoted command and use the output (stdout) from that command.

It is best to use CODE tags for posting segments of scripts.

You probably mean this:


#!/bin/bash                                                a script should always start with a shebang!
cd $1
mkdir aif                                               # create the aif subdirectory
for file in *.aif do                                    # work on all files with suffix .aif
        #echo $file
        name=$(basename -s .aif ${file})                # remove the path and the .aif suffix
        #echo $name
        wave=${name}.wav                                # add the .wav suffix
        #echo $wave
        sox $file $wave                                 # convert the file: sox file file.wav
        mv $file aif                                    # move the .aif file to the aif directory
done

Remarks:

  • I don not know if what you posted is only a snippet, but when it is supposed to be a complete script, then the shebang is missing;
  • those things at the end of the file name starting with a . (dot) are called “suffix” in Unix/Linux, that is because the word “extension” has a special meaning in MS-DOS file identification;
  • I hope you read the man page of basename by now, thus I can refrain from explaning what the -s option does;
  • I prefer the $( … ) construct above the .... construct; it is better readable, can be nested and exists already for decades, thus there is no need to fall back to the archaic version (sorry @nrickert);
  • “name” does not now have the suffix anymore, thus this does “sox file file.wav” should that note be “sox file.aif file.wav”? And it moves “file” which does not exist, “file.aif” does exist.

I guess you want to convert all files with suffix .aif (hoping they contain AIF formatted data) to a file of WAF formatted data and suffix .waf and also move the original file to the sub-directory aif.

To begin with you do a cd to the directory, which means that “file in *.aif” will only give you file names without any path. Thus why the use of basename? Furher shortening brings me to:

#!/bin/bash
cd $1
mkdir aif
for file in *.aif
do
        sox ${file} ${file%.aif}.waf
        mv $file aif/
done

Hi,

First thing, quote your variables “$1” not** $1.
** “$file” not $file and so on. That way your variables are not subjected to world splitting.

When using cd in a script it is a good practice to add an exit if it failed.

cd "$1" || exit

So the script will exit immediately and will not execute the rest of the code.

Here is an example why.

#!/bin/bash

# cd to directory that does not exists
cd /directory/with/files 

printf '%s
' 'rm this' 'rm that' 'mv this' 'mv that'

If you run that, the output will be.

myscript: line 4: cd: /directory/with/files: No such file or directory
rm this
rm that
mv this
mv that

Indeed cd failed, because there was an error message but the rest of the script got executed. Imagine of you ran that script inside your “$HOME” directory…

Now with the exit.

#!/bin/bash

# cd to directory that does not exists
cd /directory/with/files || exit

printf '%s
' 'rm this' 'rm that' 'mv this' 'mv that'

The output is.

myscript: line 4: cd: /directory/with/files: No such file or directory

The script exited with an error message and rest of the code was not executed.

With the mkdir, I always use the -p option, have a look at the --help option.

mkdir --help | grep -- -p

You should see something like.

-p, --parents     no error if existing, make parent directories as needed

In short if you’re trying to create a directory that is already existing you will not have an error, **mkdir **will move on.

Now with the loop and you want to strip the pathname from the file name, you could do a P.E. parameter expansion instead.

for file in *.aif; do
  echo "${file##*/}"
done

You can assign it in a variable

variable=${file##*/}

have a look at the section of the bash manual for that.

PAGER='less +/^:space:]]*parameter\ expansion' man bash

To be exact see.

man bash | grep -FA4 '${parameter##word}'

Also put an echo before each command you want to execute like when running sox, and mv.

echo sox "$file" "$wave"

and

echo mv "$file" aif

In that way you should see what is going to be executed, remove it when you’re satisfied with the output.

Also removing/replacing the file extension can be done with.

"${file%.mp3}"

or add a new extesion

"${file%.mp3}.avi"