从 shell 对列表执行操作

Ehe*_*Tov 3 shell freebsd bash

我有一个要卸载的软件包列表。卸载程序pkg_deinstall不会将软件包列表作为卸载的参数。我将如何从列表中卸载(如 foreach 循环)?

[root@fbsd01 /usr/ports/editors/vim]# pkg_info | grep proto| sed 's/\([a-z0-9]*\).*/\1/'
bigreqsproto
compositeproto
damageproto
fixesproto
fontsproto
inputproto
kbproto
randrproto
renderproto
xcb
xcmiscproto
xextproto
xf86bigfontproto
xineramaproto
Run Code Online (Sandbox Code Playgroud)

我认为与此类似的命令会起作用,但我必须将列表作为参数而不是流传递: pkg_info | grep proto| sed 's/\([a-z0-9]*\).*/\1/' | head -n 1 pkg_deinstall

如果你能给我一些关于使用什么程序和语法的线索,那会很有帮助。我知道由于它是独一无二的,您可能很难想出确切的答案。如果我的问题太复杂,也许有人可以告诉我如何对ls目录中的文件执行操作。

Sté*_*nez 5

对于最基本的“foreach” xargs,它读取一些参数并将它们附加到其他一些命令行。例如,您可以尝试:

> cut -d: -f1 /etc/passwd | xargs -n1 echo user:
Run Code Online (Sandbox Code Playgroud)

请注意,在用户名可能包含空格字符的情况下,您应该传递一个-d'\n'参数xargs。要将所有¹参数附加到同一命令,请使用:

> cut -d: -f1 /etc/passwd | xargs echo users:
Run Code Online (Sandbox Code Playgroud)

对于更一般的循环,你可以使用这个:

> cut -d: -f1 /etc/passwd | while read i; do echo $i; done
Run Code Online (Sandbox Code Playgroud)

这一次,$i可以放置在一个或多个命令序列中的任何位置。一次读取一行输入,并存储在变量中i。也可以拆分² 行并将其存储在多个变量中:

> cut -d: -f1,6 /etc/passwd --output-delimiter=' ' | \
  while read i j; do echo home directory of user $i is $j; done
Run Code Online (Sandbox Code Playgroud)

请注意,对于原始文件名的循环,以下内容更好(请参阅评论):

> for i in *.txt; do echo file: $i; done
Run Code Online (Sandbox Code Playgroud)


1. 更准确地说:系统允许的数量。
2.根据IFS变量

  • 解析`ls` 的输出以对文件进行操作是[要避免的](http://mywiki.wooledge.org/ParsingLs)。使用 shell globing,例如 `for file in *; do [...] done` 或 `find -exec` 代替。在这个 OP 的问题中,他们已经生成了一个包列表,因此将其放入 while 读取循环可能没问题,但对于文件名则不然! (2认同)