2

我正在阅读此链接上的指南 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),当它mv "$1"在上面的语句中说明 $1 的含义时,
4) 最后 find 命令正在关闭,-exec <something> _ {} \;
现在下划线 _ 的用途是什么,卷曲大括号 {} 和一个反斜杠,后跟一个冒号 \;?
在第三个例子中,他们说

# 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 

我不清楚以下几行
5)[ -f "$file" ] || continue # ignore non-existing names
我不清楚 [ ] 如果 $file 存在则测试条件,那么 OR 条件有什么用 || 这里和继续声明
6)[ -f "$newname" ] && continue # don't overwrite existing files这里的疑问与第 5 点相同

4

2 回答 2

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}替换第一次出现的patternin parameterby string,其中${parameter//pattern/string}替换所有匹配项。

对于第二部分:

  1. dir=${1%/*}

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

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

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

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

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

  5. 不知何故,这是完全独立的:你有条件、一个or运算符和运算符的第二部分,它们可以作为一个整体阅读为

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

  6. 正如您所指出的那样,除了运算符之外,情况完全相同,这一次导致解释为:

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

    另一种阅读方式是

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

您可以在最初的问题中获得更多信息,有关参数扩展,来自man bash | less -p "Parameter Expansion".

于 2013-03-09T08:31:09.617 回答
1
${f// /_}

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

ref


${1%/*}

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

ref


${1##*/}

*/意思是:从字符串的前面删除最长的匹配

ref


当它说mv "$1"$1 是什么意思时

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

echo $1

你这样打电话

foo.sh 111

那么输出将是

111

终于 find 命令被关闭了,-exec <something> _ {} \; 现在下划线_、花括号{}和反斜杠后跟冒号有什么用\;

下划线是参数的占位符$0

ref

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

ref


[ -f "$file" ] || continue

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

ref

于 2013-03-09T08:45:01.490 回答