在bash中重命名文件的陷阱

时间:2013-03-09 07:51:06

标签: bash posix renaming

我在这里阅读指南 http://mywiki.wooledge.org/BashFAQ/030 在这个链接上给出了一些例子我试图理解它们的一个示例代码说

# Bash
# Replace all spaces with underscores
for f in *\ *; do mv -- "$f" "${f// /_}"; done
到目前为止,我所知道的是在搜索和替换的情况下使用反斜杠来表示特殊字符,如〜或#等空格 例子或shell脚本在上面的例子中他们有 使用${f// /_}
向前斜线,我不清楚这是允许的吗? 在同一页面上的另一个例子中 他们举一个例子来删除空格并用下划线替换它

find . -depth -name "* *" -exec bash -c 'dir=${1%/*} base=${1##*/};
mv "$1" "$dir/${base// /_}"' _ {} \;

在上面的例子中我不清楚以下
1)dir=${1%/*}
2)base=${1##*/}
3)当上述陈述中{1}表示1美元的含义时, 4)最后使用mv "$1"来关闭查找命令 现在使用下划线_,花括号{}和反斜杠后面跟着一个冒号是什么?;?
在第三个例子中,他们说

-exec <something> _ {} \;

我不清楚以下几行 5)# tolower - convert file names to lower case # POSIX for file in "$@"do [ -f "$file" ] || continue # ignore non-existing names newname=$(echo "$file" | tr '[:upper:]' '[:lower:]') # lower case [ "$file" = "$newname" ] && continue # nothing to do [ -f "$newname" ] && continue # don't overwrite existing files mv -- "$file" "$newname"done
我不清楚[]测试条件是否存在$ file然后OR条件的使用是什么||这里和继续声明
6)[ -f "$file" ] || continue # ignore non-existing names这里的疑问与第5点相同

2 个答案:

答案 0 :(得分:1)

关于第一个问题,关于替换,你有man bash

  

$ {参数/模式/字符串}

 Pattern substitution. ... If pattern begins with /, all matches
of  pattern  are replaced   with  string.   Normally  only
the  first  match  is replaced.

这意味着${parameter/pattern/string}替换patternparameter的{​​{1}}第一次出现string,其中${parameter//pattern/string}替换所有匹配。

第二部分:

  1. dir=${1%/*}

    $1是脚本的第一个参数,可以通过等效${1}访问,它允许参数扩展,例如%...,删除${1}中最短的匹配模式。 1}},将模式视为/*;

  2. base=${1##*/}

    这会删除最长的匹配前缀##,考虑模式*/;这意味着,在x="a/b/c/d"中,${x##*/}将为您提供d;

  3. 如前所述,$1是你脚本的第一个参数;

  4. 后跟冒号的反斜杠纯粹是语法,需要导致-exec ...停止解析命令行 - 指向命令的结尾;

  5. ,以某种方式,非常自包含:你有条件,一个or运算符,以及运算符的第二部分,可以整体读取,作为< / p>

      

    如果$ file存在,转到下一行,或者/否则,继续(跳过for循环的当前迭代);

  6. 以及你指出的情况是完全一样的,除了操作员,导致解释,这一次,是:

      

    如果名为$ newname的文件已存在,请跳至下一次迭代;

    另一种阅读方式是

      

    名为$ newname的文件存在并跳到下一次迭代。

  7. 您可以从man bash | less -p "Parameter Expansion"获取有关参数扩展的初始问题的更多信息。

答案 1 :(得分:1)

${f// /_}

表示:用下划线替换所有出现的空格

ref


${1%/*}

表示:从字符串末尾删除/*的最短匹配

ref


${1##*/}

表示:从字符串前面删除*/的最长匹配

ref


  

当它表示mv "$1" $ 1的含义时

$1是第一个位置参数。所以如果你的脚本有这个

echo $1

你打电话就是这样

foo.sh 111

然后输出

111

  

最后使用-exec <something> _ {} \;关闭了find命令   现在使用下划线_,花括号{}和反斜杠是什么用法   然后是\;上方的冒号?

下划线是参数$0

的占位符

ref

{} \;成语与find一起使用,说:对每个文件运行一次此命令

ref


[ -f "$file" ] || continue

表示:如果$file不是FILE,则继续(立即结束循环的当前迭代并开始下一个)

ref