从 bash 中的 $@ 中删除第一个元素 [重复]

Posted

技术标签:

【中文标题】从 bash 中的 $@ 中删除第一个元素 [重复]【英文标题】:Remove first element from $@ in bash [duplicate] 【发布时间】:2011-02-11 16:25:48 【问题描述】:

我正在编写一个 bash 脚本,它需要遍历传递给脚本的参数。但是,第一个参数不应该被循环,而是需要在循环之前进行检查。

如果我不必删除第一个元素,我可以这样做:

for item in "$@" ; do
  #process item
done

我可以修改循环以检查它是否在第一次迭代中并更改行为,但这似乎太老套了。必须有一种简单的方法来提取第一个参数,然后遍历其余参数,但我找不到它。

【问题讨论】:

【参考方案1】:

使用shift?

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html

基本上,为循环前的第一个参数读取$1(或$0,如果您要检查的是脚本名称),然后使用shift,然后循环剩余的$@

【讨论】:

看,我知道有一个简单的答案。 :) 值得一票,但 丹尼斯的回答被接受 :) @mgarciaisaia 似乎更适合 OP 的要求:删除第一项 这完全是模糊的——不如下面的@nos 回答有用 有一个例子会很有用,以避免不得不去一个可能有一天会消失的外部链接。【参考方案2】:

另一种变体使用数组切片:

for item in "$@:2"
do
    process "$item"
done

如果由于某种原因您想保留参数,这可能很有用,因为 shift 具有破坏性。

【讨论】:

感谢 $@:2。好东西! 正是我想要的。现在不需要 temp 变量来取消引用 "$!1$@:2" 中的第一个参数 @Herms 这应该是公认的答案,更具可读性且无破坏性(相对于 shift) 漂亮,非常感谢。 从技术上讲,当前接受的答案是正确的,但这在技术上和实践上都是正确的(因为 shift 具有破坏性)。这是一个更好的答案。所以理想情况下应该是答案。【参考方案3】:
firstitem=$1
shift;
for item in "$@" ; do
  #process item
done

【讨论】:

记住$0一般是脚本名。 +1 用于展示一个简单的例子;请注意,in "$@" 部分是隐含的,可以省略。 @mklement0 你是说你可以做“for item; do”? @DavidDoria:是的,你可以。试试set -- 1 'two' 'three four'; for item; do echo "[$item]"; done【参考方案4】:
q=$@:0:1;[ $2 ] && set $@:2 || set ""; echo $q

编辑

> q=$@:1
# gives the first element of the special parameter array $@; but $@ is unusual in that it contains (? file name or something ) and you must use an offset of 1;

> [ $2 ] 
# checks that $2 exists ; again $@ offset by 1
    > && 
    # are elements left in        $@
      > set $@:2
      # sets parameter value to   $@ offset by 1
    > ||
    #or are not elements left in  $@
      > set ""; 
      # sets parameter value to nothing

> echo $q
# contains the popped element

一个带有规则数组的pop示例

   LIST=( one two three )
    ELEMENT=( $LIST[@]:0:1 );LIST=( "$LIST[@]:1" ) 
    echo $ELEMENT

【讨论】:

请同时解释代码以更具教育意义。 q=$@:0:1 (顺便说一句,您的解释错误地将其引用为q=$@:1)应该是q=$@:1:1 更清楚:$@ 以索引 1 开头,大概是并行的显式 $1, $2, ... 参数 - 元素 0 具有 no 值(与其显式对应物 $0 不同,它反映了 shell / 脚本文件)。 [ $2 ]break 应该 $2 包含嵌入的空格;如果您改用[[ $2 ]],就不会遇到这个问题。也就是说,不需要条件和 || 分支:如果只有 1 个参数,$@:2 将简单地扩展为空字符串(续)。 (cont'd) 但是,您应该使用 set -- 以确保恰好看起来像选项的参数不会被 set 解释为这样,并且您应该双引号$@:2 引用和$q 引用在echo 语句中。此时我们得到:q=$@:1:1; set -- "$@:2"; echo "$q"。然而,q=$@:1:1 只是另一种(更繁琐的)表达$1 的方式,其余的基本上重新实现了shift 命令;使用这些功能我们很容易得到:q=$1; shift; echo "$q". @mklement0 我想知道在哪里放置 printf 来清理路径的好地方? (我希望我能更清楚) 很遗憾,我不明白。有哪些路径?用什么方式清洁?

以上是关于从 bash 中的 $@ 中删除第一个元素 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何从字典中的列表中删除元素[重复]

如何从bash中的多个文件名中删除公共前缀模式[重复]

从 Bash 数组中删除一个元素

如何删除bash数组中的确切元素?

数组作为 Bash 中函数的参数:仅返回第一个元素 [重复]

从Ruby中的数组中删除重复元素