How can I put the directory (not full path) of the file which opened the script into a variable? I assume this is the same as $1, so I would like file's path to yield the same result when executed from terminal.

Explained;

#!/bin/bash
script.sh '~/foo/bar/file.ext'

#I want to put "bar" into a variable.

It should also work when "file.ext" opens with "script.sh" through GUI.

有帮助吗?

解决方案

You should checkout both the dirname and basename programs, The dirname program takes an argument and removes the name of the program from the rest of the path. That is, it will give you the directory name.

The basename program does the opposite. Given the name of a path, it will remove all directories and just leave the file name:

$ dirname /one/two/three/four/five.txt
/one/two/three/four
$ basename /one/two/three/four/five.txt
five.txt

Now, the rest depends upon the shell. In BASH (which is the default shell on Linux and what you've tagged, you can use the $(command) syntax. This takes the output of the command and replaces it on the command line. For example:

$ mydirectory=$(dirname /one/two/three/four/five.txt)
$ echo $mydirectory
/one/two/three/four

In the above example, the dirname command took the name of the directory, replaced everything in the $() syntax and allowed me to set the name of my variable mydirectory.

You can use them in combination to get what you want:

$ my_full_dir=$(dirname "~/foo/bar/file.ext")
$ echo $my_full_dir
~/foo/bar
$ my sub_dir=$(basename $my_full_dir)
$ echo $sub_dir
bar

You can also combine the basename and dirname commands together:

$ my_sub_dir=$(basename $(dirname "~/foo/bar/file.ext"))
$ echo $my_sub_dir
$ bar

When a shell program executes, it puts each and every parameter on the command line into a count variable. For example:

$ myprog alpha beta gamma delta

Inside of the program myprog, the following variables are set:

$1 = "alpha"
$2 = "beta"
$3 = "gamma"
$4 = "delta"

One more thing with the BASH shell: There's a special filter syntax to parse variables.

  • ${variable#pattern} - Left small pattern. Removes the smallest pattern from the left side of the variable
  • ${variable##pattern} - Left large pattern. Removes the largest pattern from the left side of the variable
  • ${variable%pattern} - Right small pattern. Removes the smallest pattern from the right side of the variable
  • ${variable%%pattern} - Right large pattern. Removes the largest possible pattern from the right side of the variable

Here's an example:

$ FOO="ONE|TWO|THREE|FOUR"
$ echo ${FOO##*|}
FOUR
$ echo ${FOO#*|}
TWO|THREE|FOUR

In the above cases, the pattern was *|. This means any combination of letters followed by a | In the first one, the smallest match was ONE|. In the second one, it was ONE|TWO|THREE|. You can also use this to simulate the basename and dirname commands:

$ myfile="~/foo/bar/file.ext"
$ echo ${myfile%/*}     #Like `dirname`
~/foo/bar
$echo ${myfile#*/}      #Like `basename`
file.txt

其他提示

Assuming your shell is /bin/bash:

echo $(basename $(dirname $1))

Add some code to your script.sh

 echo '$1='"$1"

 inputFile=$1

 inputPath=${inputFile%/*}
 finalDir=${inputPath##*/}

 echo '$inputFile='"${inputFile}"
 echo '$inputPath='"${inputPath}"
 echo '$finalDir='"${finalDir}"

output

  ...
  $finalDir=bar

Does this give you the results you want?

I hope this helps.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top