Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash Shell脚本:更改文件夹名称中的工作目录和空格_Bash_Shell - Fatal编程技术网

Bash Shell脚本:更改文件夹名称中的工作目录和空格

Bash Shell脚本:更改文件夹名称中的工作目录和空格,bash,shell,Bash,Shell,我想制作一个脚本,该脚本采用文件路径作为参数,并将CD放入其文件夹中。 这是我做的: #!/bin/bash #remove the file name, and change every space into \space shorter=`echo "$1" | sed 's/\/[^\/]*$//' | sed 's/\ /\\\ /g'` echo $shorter cd $shorter 我实际上有两个问题(我是shell脚本的新手): 如何使cd“持久化”?我想把这个脚本放到

我想制作一个脚本,该脚本采用文件路径作为参数,并将CD放入其文件夹中。 这是我做的:

#!/bin/bash

#remove the file name, and change every space into \space
shorter=`echo "$1" | sed 's/\/[^\/]*$//' | sed 's/\ /\\\ /g'`

echo $shorter
cd $shorter
我实际上有两个问题(我是shell脚本的新手):

  • 如何使cd“持久化”?我想把这个脚本放到/usr/bin中,然后从文件系统中的任何地方调用它。返回脚本后,我想留在
    $shorter
    文件夹中。基本上,如果pwd是/usr/bin,我可以通过键入
    来实现。script/my/path
    而不是
    /script/my/path
    ,但是如果我在其他文件夹中呢

  • 第二个问题比较棘手。只要给定参数中有空格,我的脚本就会失败。虽然
    $shorter
    正是我想要的(例如
    /home/jack/my\folder/subfolder
    ),但cd失败,错误为
    /usr/bin/script:line 4:cd:/home/jack/my\:没有此类型的文件或文件夹。我想我什么都试过了,用
    cd'$shorter'
    cd'''$shorter'''
    都没有用。我错过了什么


非常感谢您的回答

对于第一部分,根本不需要
较短的
变量。您只需执行以下操作:

#!/bin/bash

cd "${1%/*}"
解释 大多数shell,包括
bash
,都有所谓的参数扩展,它们非常强大和高效,因为它们允许您在shell中本地操作通常需要调用外部二进制文件的变量

可以通过外部调用使用参数扩展的两个常见示例如下:

${var%/*} # replaces dirname
${var##*/} # replaces basename
有关详细信息,请参见本常见问题解答。事实上,当你在那里时,不妨回顾一下整个常见问题解答

第一部分:

  • 目录的更改在脚本的生命周期之后不会“持久”,因为脚本在新的shell进程中运行。但是,您可以使用shell别名或shell函数。例如,您可以将代码嵌入shell函数,并在
    .bash\u概要文件
    或其他源位置定义它

    mycdfunction () {
         cd /blah/foo/"$1"
    }
    
至于“名称中的空格”位:

  • 在Bourne shell中引用变量的一般语法是:
    “$var”
    -
    “双引号”
    告诉shell展开其中的任何变量,但将结果分组为单个参数

  • 省略
    $var
    周围的双引号会告诉shell展开变量,但随后会将结果拆分为空格上的参数(“单词”)。通常,这就是shell拆分参数的方式

  • 使用
    “单引号”
    会使shell不展开任何内容,而是将参数分组在一起

  • 您可以在键入(或在脚本中)时使用
    \
    (反斜杠空白)来转义空格,但这通常比使用
    “单引号”或
    “双引号”
    更难阅读

请注意,扩展阶段包括:
$variables
通配符*
{grouping,names}和大括号
$(echo命令替换)
和其他效果

                    |   expansion    |   no expansion
      -------------------------------------------------------
        grouping    |     "  "       |    '   '
        splitting   |  (no punc.)    |  (not easily done)

.bashrc
中添加以下行:

function shorter() { cd "${1%/*}"; }
  • %
    表示从末端移除较小的图案
  • /*
    是模式
然后在终端中:

$ . ~/.bashrc   # to refresh your bash configuration
$ type shorter  # to check if your new function is available
shorter is a function
shorter () 
{ 
    cd "${1%/*}"
}
$ shorter ./your/directory/filename  # this will move to ./your/directory

当您将脚本放入
/usr/bin
中时,您可以在任何地方调用它。要处理shell中的空白,只需将目标放在“”之间(但这并不重要!!)。 这是一个演示:

#!/bin/bash

#you can use dirname but that's not apropriate
#shorter=$(dirname $1)
#Use parameter expansion (too much better)
shorter=${1%/*}

echo $shorter

另一种方法是,因为您的Mac电脑上有
dirname

#!/bin/sh
cd "$(dirname "$1")"
由于您在评论中提到希望能够将文件拖动到窗口中并
cd
,因此您可能希望使脚本允许文件或目录路径作为参数:

#!/bin/sh
[ -f "$1" ] && set "$(dirname "$1")"  # convert a file to a directory
cd "$1"

如果使用整个文件路径作为参数。。。为什么不直接使用内置的
cd/path/to/file
?关于空间,请添加双引号:
cd“$shorter”
。好吧,如果它能工作的话,我会喜欢它的,但我拥有的是:
bash:cd:/home/jack/Images/P1220527.JPG:不是文件夹
。既然
mancd
不存在,我不认为有任何选项可以让它工作。。。这在你的电脑上真的有效吗?你用什么发行版?我想我已经试过双引号了。不过我又试了一次。它仍然不起作用,但略有不同:我有
/usr/bin/script:line 4:cd:/home/jack/this\is\a\space:没有这种类型的文件或文件夹
。现在它确实考虑了完整的路径,但在空间上仍然失败…只是为了澄清一下。。。我之前的评论是:这个脚本似乎只是重新实现了正常的
cd
命令的功能。这个剧本只是为了练习吗?哇!就这么简单!谢谢!但是“${1%/*}”到底是什么意思?有两件事1)请不要像那样试图解析
ls
,它会以可怕的方式崩溃。相反,只需使用shell的本机语法:
for i in*;做完成
2)而不是对
dirname
的外部调用,而是使用参数扩展
${var%/*}
谢谢,但我正试图让我们的新手朋友更清楚地了解事情,而且“dirname”是出于某种原因而存在的!!我对使事情变得更友好没有问题,但是像那样使用
ls
并不能使它变得更友好,而是破坏了代码。只要看看如果文件名中有空格(这很常见),会发生什么情况
dirname
之所以存在,是因为它早于参数扩展,而且许多使用shell的人甚至不知道它的存在(我知道我有很长一段时间不知道它的存在)。它使代码更高效,因为它不会导致shell自身分叉来执行外部二进制文件。关于ls,我同意你的看法。谢谢你提供的第二个信息,