How to drop an argument (from the list of arguments) in a shell script?
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
I have the following (MWE) shell script foo
:
#!/bin/bash
ARGS=("$@") # all arguments
## => if it exists, we need to drop the argument "-D" here
ls -l $ARGS[@] | sort -fk8
If foo
is called with argument -D
(the position in the list of arguments is unknown), how can I remove -D
from the list of arguments? I found out that unset ARGS[$#ARGS[@]-1]
can drop the last argument, for example, but I'm not sure in which order the arguments are passed (so I first need to know at which place the argument is and then remove it in case it is provided).
bash shell-script
add a comment |Â
up vote
0
down vote
favorite
I have the following (MWE) shell script foo
:
#!/bin/bash
ARGS=("$@") # all arguments
## => if it exists, we need to drop the argument "-D" here
ls -l $ARGS[@] | sort -fk8
If foo
is called with argument -D
(the position in the list of arguments is unknown), how can I remove -D
from the list of arguments? I found out that unset ARGS[$#ARGS[@]-1]
can drop the last argument, for example, but I'm not sure in which order the arguments are passed (so I first need to know at which place the argument is and then remove it in case it is provided).
bash shell-script
Why do you need it?
â choroba
Nov 11 '17 at 11:52
That's why: emacs.stackexchange.com/questions/36798/⦠and because I'm simply interested in how this can be done in shell scripts.
â Marius Hofert
Nov 11 '17 at 11:56
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have the following (MWE) shell script foo
:
#!/bin/bash
ARGS=("$@") # all arguments
## => if it exists, we need to drop the argument "-D" here
ls -l $ARGS[@] | sort -fk8
If foo
is called with argument -D
(the position in the list of arguments is unknown), how can I remove -D
from the list of arguments? I found out that unset ARGS[$#ARGS[@]-1]
can drop the last argument, for example, but I'm not sure in which order the arguments are passed (so I first need to know at which place the argument is and then remove it in case it is provided).
bash shell-script
I have the following (MWE) shell script foo
:
#!/bin/bash
ARGS=("$@") # all arguments
## => if it exists, we need to drop the argument "-D" here
ls -l $ARGS[@] | sort -fk8
If foo
is called with argument -D
(the position in the list of arguments is unknown), how can I remove -D
from the list of arguments? I found out that unset ARGS[$#ARGS[@]-1]
can drop the last argument, for example, but I'm not sure in which order the arguments are passed (so I first need to know at which place the argument is and then remove it in case it is provided).
bash shell-script
asked Nov 11 '17 at 11:39
Marius Hofert
2441411
2441411
Why do you need it?
â choroba
Nov 11 '17 at 11:52
That's why: emacs.stackexchange.com/questions/36798/⦠and because I'm simply interested in how this can be done in shell scripts.
â Marius Hofert
Nov 11 '17 at 11:56
add a comment |Â
Why do you need it?
â choroba
Nov 11 '17 at 11:52
That's why: emacs.stackexchange.com/questions/36798/⦠and because I'm simply interested in how this can be done in shell scripts.
â Marius Hofert
Nov 11 '17 at 11:56
Why do you need it?
â choroba
Nov 11 '17 at 11:52
Why do you need it?
â choroba
Nov 11 '17 at 11:52
That's why: emacs.stackexchange.com/questions/36798/⦠and because I'm simply interested in how this can be done in shell scripts.
â Marius Hofert
Nov 11 '17 at 11:56
That's why: emacs.stackexchange.com/questions/36798/⦠and because I'm simply interested in how this can be done in shell scripts.
â Marius Hofert
Nov 11 '17 at 11:56
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
3
down vote
accepted
The no-frills approach is to simply loop over the positional parameters, collecting all but -D
into an array, and then use set --
to update the params:
for param; do
[[ ! $param == '-D' ]] && newparams+=("$param")
done
set -- "$newparams[@]" # overwrites the original positional params
In bash, you can even donewparams+=("$param")
.
â choroba
Nov 11 '17 at 12:13
Oh, yeah. I always forget if Bash has that or not. Thanks for the reminder.
â B Layer
Nov 11 '17 at 12:15
Downvoted because...why?
â B Layer
Nov 25 '17 at 20:53
add a comment |Â
up vote
4
down vote
With zsh
, use the $array:#pattern
parameter expansion operator:
$ set foo -D -D bar '' $'anb'
$ printf '<%s>n' "$@:#-D"
<foo>
<bar>
<>
<a
b>
POSIXly:
for i do
[ "$i" = -D ] || set -- "$@" "$i"
shift
done
printf '<%s>n' "$@"
BTW, you forgot the quotes, --
and -d
:
ls -ld -- "$@"
If you want to sort by modification time, you can just use the -t
option, here with -r
(reverse) for oldest first:
ls -lrtd -- "$@"
Beware that if $ARGS
is an empty array, it will list .
. So you can do:
[ "$@" -eq 0 ] || ls -lrtd -- "$@"
To sort reliably based on the hour of the day irrespective of date, with zsh
and a ls
implementation that supports -U
for not sorting:
zmodload zsh/stat # best in ~/.zshrc
bytime() zstat -LA REPLY -F%T +mtime -- $REPLY
ls --full-time -ldU -- .(e'reply=("$@")'o+bytime)
With limited shells like bash
, it's very hard to sort files based on arbitrary metadata like that. Again, if you've got access to recent GNU tools, it's slightly easier:
[ "$#" -gt 0 ] && (
export LC_ALL=C
printf '%s' "$@" |
sed -z 's|^-$|./-|' |
xargs -r0 stat --printf '%yt%n' -- |
sort -zk2,2 |
cut -zf 2-
) | xargs -r0 ls -lUd --
Portably (but still using the non-standard ls -U
here), it's generally easier to resort to perl
, like:
perl -MPOSIX -e '
exec qwls -ldU --,
map $_->[1]
sort $a->[0] cmp $b->[0]
map [strftime("%T", localtime((lstat$_)[9])), $_]
@ARGV' -- "$@"
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
The no-frills approach is to simply loop over the positional parameters, collecting all but -D
into an array, and then use set --
to update the params:
for param; do
[[ ! $param == '-D' ]] && newparams+=("$param")
done
set -- "$newparams[@]" # overwrites the original positional params
In bash, you can even donewparams+=("$param")
.
â choroba
Nov 11 '17 at 12:13
Oh, yeah. I always forget if Bash has that or not. Thanks for the reminder.
â B Layer
Nov 11 '17 at 12:15
Downvoted because...why?
â B Layer
Nov 25 '17 at 20:53
add a comment |Â
up vote
3
down vote
accepted
The no-frills approach is to simply loop over the positional parameters, collecting all but -D
into an array, and then use set --
to update the params:
for param; do
[[ ! $param == '-D' ]] && newparams+=("$param")
done
set -- "$newparams[@]" # overwrites the original positional params
In bash, you can even donewparams+=("$param")
.
â choroba
Nov 11 '17 at 12:13
Oh, yeah. I always forget if Bash has that or not. Thanks for the reminder.
â B Layer
Nov 11 '17 at 12:15
Downvoted because...why?
â B Layer
Nov 25 '17 at 20:53
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
The no-frills approach is to simply loop over the positional parameters, collecting all but -D
into an array, and then use set --
to update the params:
for param; do
[[ ! $param == '-D' ]] && newparams+=("$param")
done
set -- "$newparams[@]" # overwrites the original positional params
The no-frills approach is to simply loop over the positional parameters, collecting all but -D
into an array, and then use set --
to update the params:
for param; do
[[ ! $param == '-D' ]] && newparams+=("$param")
done
set -- "$newparams[@]" # overwrites the original positional params
edited Nov 12 '17 at 7:11
answered Nov 11 '17 at 12:00
B Layer
3,9241525
3,9241525
In bash, you can even donewparams+=("$param")
.
â choroba
Nov 11 '17 at 12:13
Oh, yeah. I always forget if Bash has that or not. Thanks for the reminder.
â B Layer
Nov 11 '17 at 12:15
Downvoted because...why?
â B Layer
Nov 25 '17 at 20:53
add a comment |Â
In bash, you can even donewparams+=("$param")
.
â choroba
Nov 11 '17 at 12:13
Oh, yeah. I always forget if Bash has that or not. Thanks for the reminder.
â B Layer
Nov 11 '17 at 12:15
Downvoted because...why?
â B Layer
Nov 25 '17 at 20:53
In bash, you can even do
newparams+=("$param")
.â choroba
Nov 11 '17 at 12:13
In bash, you can even do
newparams+=("$param")
.â choroba
Nov 11 '17 at 12:13
Oh, yeah. I always forget if Bash has that or not. Thanks for the reminder.
â B Layer
Nov 11 '17 at 12:15
Oh, yeah. I always forget if Bash has that or not. Thanks for the reminder.
â B Layer
Nov 11 '17 at 12:15
Downvoted because...why?
â B Layer
Nov 25 '17 at 20:53
Downvoted because...why?
â B Layer
Nov 25 '17 at 20:53
add a comment |Â
up vote
4
down vote
With zsh
, use the $array:#pattern
parameter expansion operator:
$ set foo -D -D bar '' $'anb'
$ printf '<%s>n' "$@:#-D"
<foo>
<bar>
<>
<a
b>
POSIXly:
for i do
[ "$i" = -D ] || set -- "$@" "$i"
shift
done
printf '<%s>n' "$@"
BTW, you forgot the quotes, --
and -d
:
ls -ld -- "$@"
If you want to sort by modification time, you can just use the -t
option, here with -r
(reverse) for oldest first:
ls -lrtd -- "$@"
Beware that if $ARGS
is an empty array, it will list .
. So you can do:
[ "$@" -eq 0 ] || ls -lrtd -- "$@"
To sort reliably based on the hour of the day irrespective of date, with zsh
and a ls
implementation that supports -U
for not sorting:
zmodload zsh/stat # best in ~/.zshrc
bytime() zstat -LA REPLY -F%T +mtime -- $REPLY
ls --full-time -ldU -- .(e'reply=("$@")'o+bytime)
With limited shells like bash
, it's very hard to sort files based on arbitrary metadata like that. Again, if you've got access to recent GNU tools, it's slightly easier:
[ "$#" -gt 0 ] && (
export LC_ALL=C
printf '%s' "$@" |
sed -z 's|^-$|./-|' |
xargs -r0 stat --printf '%yt%n' -- |
sort -zk2,2 |
cut -zf 2-
) | xargs -r0 ls -lUd --
Portably (but still using the non-standard ls -U
here), it's generally easier to resort to perl
, like:
perl -MPOSIX -e '
exec qwls -ldU --,
map $_->[1]
sort $a->[0] cmp $b->[0]
map [strftime("%T", localtime((lstat$_)[9])), $_]
@ARGV' -- "$@"
add a comment |Â
up vote
4
down vote
With zsh
, use the $array:#pattern
parameter expansion operator:
$ set foo -D -D bar '' $'anb'
$ printf '<%s>n' "$@:#-D"
<foo>
<bar>
<>
<a
b>
POSIXly:
for i do
[ "$i" = -D ] || set -- "$@" "$i"
shift
done
printf '<%s>n' "$@"
BTW, you forgot the quotes, --
and -d
:
ls -ld -- "$@"
If you want to sort by modification time, you can just use the -t
option, here with -r
(reverse) for oldest first:
ls -lrtd -- "$@"
Beware that if $ARGS
is an empty array, it will list .
. So you can do:
[ "$@" -eq 0 ] || ls -lrtd -- "$@"
To sort reliably based on the hour of the day irrespective of date, with zsh
and a ls
implementation that supports -U
for not sorting:
zmodload zsh/stat # best in ~/.zshrc
bytime() zstat -LA REPLY -F%T +mtime -- $REPLY
ls --full-time -ldU -- .(e'reply=("$@")'o+bytime)
With limited shells like bash
, it's very hard to sort files based on arbitrary metadata like that. Again, if you've got access to recent GNU tools, it's slightly easier:
[ "$#" -gt 0 ] && (
export LC_ALL=C
printf '%s' "$@" |
sed -z 's|^-$|./-|' |
xargs -r0 stat --printf '%yt%n' -- |
sort -zk2,2 |
cut -zf 2-
) | xargs -r0 ls -lUd --
Portably (but still using the non-standard ls -U
here), it's generally easier to resort to perl
, like:
perl -MPOSIX -e '
exec qwls -ldU --,
map $_->[1]
sort $a->[0] cmp $b->[0]
map [strftime("%T", localtime((lstat$_)[9])), $_]
@ARGV' -- "$@"
add a comment |Â
up vote
4
down vote
up vote
4
down vote
With zsh
, use the $array:#pattern
parameter expansion operator:
$ set foo -D -D bar '' $'anb'
$ printf '<%s>n' "$@:#-D"
<foo>
<bar>
<>
<a
b>
POSIXly:
for i do
[ "$i" = -D ] || set -- "$@" "$i"
shift
done
printf '<%s>n' "$@"
BTW, you forgot the quotes, --
and -d
:
ls -ld -- "$@"
If you want to sort by modification time, you can just use the -t
option, here with -r
(reverse) for oldest first:
ls -lrtd -- "$@"
Beware that if $ARGS
is an empty array, it will list .
. So you can do:
[ "$@" -eq 0 ] || ls -lrtd -- "$@"
To sort reliably based on the hour of the day irrespective of date, with zsh
and a ls
implementation that supports -U
for not sorting:
zmodload zsh/stat # best in ~/.zshrc
bytime() zstat -LA REPLY -F%T +mtime -- $REPLY
ls --full-time -ldU -- .(e'reply=("$@")'o+bytime)
With limited shells like bash
, it's very hard to sort files based on arbitrary metadata like that. Again, if you've got access to recent GNU tools, it's slightly easier:
[ "$#" -gt 0 ] && (
export LC_ALL=C
printf '%s' "$@" |
sed -z 's|^-$|./-|' |
xargs -r0 stat --printf '%yt%n' -- |
sort -zk2,2 |
cut -zf 2-
) | xargs -r0 ls -lUd --
Portably (but still using the non-standard ls -U
here), it's generally easier to resort to perl
, like:
perl -MPOSIX -e '
exec qwls -ldU --,
map $_->[1]
sort $a->[0] cmp $b->[0]
map [strftime("%T", localtime((lstat$_)[9])), $_]
@ARGV' -- "$@"
With zsh
, use the $array:#pattern
parameter expansion operator:
$ set foo -D -D bar '' $'anb'
$ printf '<%s>n' "$@:#-D"
<foo>
<bar>
<>
<a
b>
POSIXly:
for i do
[ "$i" = -D ] || set -- "$@" "$i"
shift
done
printf '<%s>n' "$@"
BTW, you forgot the quotes, --
and -d
:
ls -ld -- "$@"
If you want to sort by modification time, you can just use the -t
option, here with -r
(reverse) for oldest first:
ls -lrtd -- "$@"
Beware that if $ARGS
is an empty array, it will list .
. So you can do:
[ "$@" -eq 0 ] || ls -lrtd -- "$@"
To sort reliably based on the hour of the day irrespective of date, with zsh
and a ls
implementation that supports -U
for not sorting:
zmodload zsh/stat # best in ~/.zshrc
bytime() zstat -LA REPLY -F%T +mtime -- $REPLY
ls --full-time -ldU -- .(e'reply=("$@")'o+bytime)
With limited shells like bash
, it's very hard to sort files based on arbitrary metadata like that. Again, if you've got access to recent GNU tools, it's slightly easier:
[ "$#" -gt 0 ] && (
export LC_ALL=C
printf '%s' "$@" |
sed -z 's|^-$|./-|' |
xargs -r0 stat --printf '%yt%n' -- |
sort -zk2,2 |
cut -zf 2-
) | xargs -r0 ls -lUd --
Portably (but still using the non-standard ls -U
here), it's generally easier to resort to perl
, like:
perl -MPOSIX -e '
exec qwls -ldU --,
map $_->[1]
sort $a->[0] cmp $b->[0]
map [strftime("%T", localtime((lstat$_)[9])), $_]
@ARGV' -- "$@"
edited Nov 11 '17 at 14:47
answered Nov 11 '17 at 12:18
Stéphane Chazelas
283k53521854
283k53521854
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f403890%2fhow-to-drop-an-argument-from-the-list-of-arguments-in-a-shell-script%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Why do you need it?
â choroba
Nov 11 '17 at 11:52
That's why: emacs.stackexchange.com/questions/36798/⦠and because I'm simply interested in how this can be done in shell scripts.
â Marius Hofert
Nov 11 '17 at 11:56