Tôi biết rằng, đã cho l="a b c"
,
echo $l | xargs ls
sản lượng
ls a b c
Năng suất xây dựng nào
mycommand -f a -f b -f c
Tôi biết rằng, đã cho l="a b c"
,
echo $l | xargs ls
sản lượng
ls a b c
Năng suất xây dựng nào
mycommand -f a -f b -f c
Câu trả lời:
Một cách để làm điều đó:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Điều này giả định a
, b
và c
không chứa khoảng trống, dòng mới, dấu ngoặc kép hoặc dấu xồ nguợc. :)
Với GNU, findutil
bạn có thể xử lý trường hợp chung, nhưng nó phức tạp hơn một chút:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Bạn có thể thay thế các |
dấu phân cách với một số nhân vật khác, điều đó không xuất hiện trong a
, b
hoặc c
.
Chỉnh sửa: Như @MichaelMol lưu ý, với một danh sách các đối số rất dài, có nguy cơ vượt quá độ dài tối đa của các đối số có thể được chuyển qua mycommand
. Khi điều đó xảy ra, cái cuối cùng xargs
sẽ phân chia danh sách và chạy một bản sao khác mycommand
, và có nguy cơ nó sẽ bị hủy bỏ -f
. Nếu bạn lo lắng về tình huống đó, bạn có thể thay thế cái cuối cùng xargs -0
bằng một thứ như thế này:
... | xargs -x -0 mycommand
Điều này sẽ không giải quyết được vấn đề, nhưng nó sẽ hủy bỏ mycommand
khi danh sách các đối số quá dài.
mycommand
. Bạn luôn có thể thêm -x
vào cuối cùng xargs
.
xargs
, và chỉ sử dụng find
nếu nó có thể được sử dụng. Giải pháp này là nguy hiểm; ít nhất bạn nên cảnh báo về trường hợp thất bại trong câu trả lời của bạn.
find
sẽ là một giải pháp chung tốt hơn, đặc biệt khi các đối số ban đầu không có tên tệp. :)
-f
và với một công cụ ví dụ ls
được sử dụng để minh họa, @ not-a-user đang xử lý tên tệp. Và đưa ra find
cung cấp -exec
đối số, cho phép bạn xây dựng một dòng lệnh, nó ổn. (Miễn mycommand
là được phép thực thi nhiều lần. Nếu không, thì chúng ta có một vấn đề khác với việc sử dụng xargs
ở đây ...)
Một cách tốt hơn để giải quyết nó (IMO) sẽ là:
trong zsh
:
l=(a b c)
mycommand -f$^l
hoặc sử dụng nén mảng để đối số không được đính kèm vào tùy chọn:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
Theo cách đó, nó vẫn hoạt động nếu l
mảng chứa các phần tử trống hoặc phần tử chứa khoảng trắng hoặc bất kỳ ký tự có vấn đề nào khác xargs
. Thí dụ:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>
trong rc
:
l=(a b c)
mycommand -f$l
trong fish
:
set l a b c
mycommand -f$l
(AFAIK rc
và fish
không có nén mảng)
Với các shell giống như Bourne kiểu cũ bash
, bạn luôn có thể làm (vẫn cho phép bất kỳ ký tự nào trong các thành phần của $@
mảng):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done;
mycommand "${args[@]}"
. IDK nếu điều này nhanh hơn, nhưng việc thêm 2 phần tử vào một mảng có vẻ như là O (n), trong khi set
vòng lặp của bạn có thể sao chép và phân tích lại danh sách arg tích lũy mỗi lần (O (n ^ 2)).
ARG_MAX
và bị-f
tách khỏi tham số được ghép nối của nó.