简体   繁体   English

Shell 破折号循环跳过前两个 arguments

[英]Shell dash for loop skip first two arguments

How to skip first two arguments using "$@" in shell dash and use the rest of arguments in for loop?如何在 shell 破折号中使用“$@”跳过前两个 arguments 并在循环中使用 ZDBC11CAA4BD5BDA99F7DZE 中的 rest?

For example, I have something like command --option file1 file2 file3 .例如,我有类似command --option file1 file2 file3的东西。 I want to skip first two arguments and loop over all the files (any number of files).我想跳过前两个 arguments 并遍历所有文件(任意数量的文件)。

I have tried using the following line:我尝试使用以下行:

files=$(echo "$@" | awk '{for (i=2; i<=NF; i++) print $i}' | tr -d '\n')

However it does not provide a line of files, but something like file1file2file3 .但是它不提供一行文件,而是提供类似file1file2file3的内容。

I would like to be able to iterate over each file name individually later in the for loop:我希望能够稍后在 for 循环中单独迭代每个文件名:

for file in "$files"
do
    rm "./desktop/temp/$file"
done

I assume that by "shell dash" you mean that you are using Dash , a light-weight shell that sticks to the Posix standard.我假设“shell dash”是指您使用的是Dash ,这是一种符合 Posix 标准的轻量级 shell 。 Comparing to Bash, Dash is quite limited and doesn't offer functionalities like arrays or complex parameter substitutions like ${@:m:n} .与 Bash 相比,Dash 非常有限,不提供 arrays 等功能或${@:m:n}等复杂参数替换。

I also assume that, by doing files=$(echo "$@" |...) you know for sure that none of your arguments contains space characters.我还假设,通过执行files=$(echo "$@" |...)你肯定知道你的 arguments 都不包含空格字符。

That said, your issue is due to the | tr -d '\n'也就是说,您的问题是由于| tr -d '\n' | tr -d '\n' part which removes the end of line that serves as a word separator. | tr -d '\n'部分删除用作单词分隔符的行尾。 That's why you get "file1file2file3".这就是你得到“file1file2file3”的原因。

But the whole command can be enhanced.但是可以增强整个命令。 Here is a better Posix-compatible way of doing this:这是一种更好的与 Posix 兼容的方法:

files=$(shift 2; printf '%s ' "$@")

( shift being done in a sub-shell, it doesn't affect the argument list in the current shell) (在子shell中完成shift ,它不会影响当前shell中的参数列表)

You may even do this:你甚至可以这样做:

(
    shift 2
    for file in "$@"; do
        rm "./desktop/temp/$file"
    done
)

(here the whole loop is executed in a subshell) (这里整个循环在一个子shell中执行)

... or write a function: ...或写一个 function:

rm_files()
{
    shift 2
    for file in "$@"; do
        rm "./desktop/temp/$file"
    done
}

rm_file "$@"

One last suggestion: is it really necessary to keep arguments 1 and 2 in the argument list?最后一个建议:真的有必要在参数列表中保留 arguments 1 和 2 吗? You could do something like:您可以执行以下操作:

arg1="$1"
arg2="$2"
shift 2
for file in "$@"; do
    rm "./desktop/temp/$file"
done

... and if you need all your arguments at once, you can do: ...如果您一次需要所有 arguments,您可以执行以下操作:

for arg in "$arg1" "$arg2" "$@"; do ...; done

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM