如果xargs是map,那么什么是过滤器?

jam*_*her 12 shell map filter xargs

我认为是xargsUNIX shell的map函数.功能是什么filter

编辑:看起来我必须更明确一点.

假设我必须提交一个接受单个字符串作为参数的程序,并返回退出代码0或1.该程序将作为它接受的字符串的谓词.

例如,我可能决定将字符串参数解释为文件路径,并将谓词定义为"此文件是否存在".在这种情况下,程序可以是test -f,给定一个字符串,如果文件存在则退出0,否则退出1.

我还必须交出一串串.例如,我可能有一个~/paths包含的文件

/etc/apache2/apache2.conf
/foo/bar/baz
/etc/hosts
Run Code Online (Sandbox Code Playgroud)

现在,我想创建一个新文件,~/existing_paths只包含我文件系统中存在的那些路径.就我而言,那就是

/etc/apache2/apache2.conf
/etc/hosts
Run Code Online (Sandbox Code Playgroud)

我想通过读取~/paths文件,通过谓词过滤这些行test -f,并将输出写入来完成此操作~/existing_paths.通过类比xargs,这看起来像:

cat ~/paths | xfilter test -f > ~/existing_paths
Run Code Online (Sandbox Code Playgroud)

这是xfilter我正在寻找的假设程序:

xfilter COMMAND [ARG]...
Run Code Online (Sandbox Code Playgroud)

对于L其标准输入的每一行,将调用COMMAND [ARG]... L,如果退出代码为0,则打印L,否则不打印任何内容.

要明确,我不是在寻找:

  • 一种过滤存在的文件路径列表的方法.这是一个具体的例子.
  • 怎么写这样的程序.我能做到.

正在寻找:

  • 一个预先存在的实现,比如xargs,或
  • 明确解释为什么不存在这一点

mru*_*cci 7

如果地图xargs,过滤器是...还是xargs.

示例:列出当前目录中的文件并过滤掉非可执行文件:

ls | xargs -I{} sh -c "test -x '{}' && echo '{}'"
Run Code Online (Sandbox Code Playgroud)

这可以通过(非生产就绪)功能方便地使用:

xfilter() {
    xargs -I{} sh -c "$* '{}' && echo '{}'"
}
ls | xfilter test -x
Run Code Online (Sandbox Code Playgroud)

或者,您可以通过GNU Parallel使用并行过滤器实现:

ls | parallel "test -x '{}' && echo '{}'"
Run Code Online (Sandbox Code Playgroud)


jm6*_*666 5

所以,你正在寻找:

 reduce(  compare(  filter( map(.. list()) ) ) )
Run Code Online (Sandbox Code Playgroud)

什么可以重新作为

 list | map | filter | compare | reduce
Run Code Online (Sandbox Code Playgroud)

主要的功能bash流水线,因此不需要有一个特殊filter和/或reduce命令.事实上,几乎所有unix命令都可以在一个(或多个)函数中起作用:

  • 名单
  • 地图
  • 过滤
  • 降低

想像:

find mydir -type f -print | xargs grep -H '^[0-9]*$' | cut -d: -f 2 | sort -nr | head  -1
^------list+filter------^   ^--------map-----------^   ^--filter--^   ^compare^  ^reduce^
Run Code Online (Sandbox Code Playgroud)

创建测试用例:

mkdir ./testcase
cd ./testcase || exit 1
for i in {1..10}
do
    strings -1 < /dev/random | head -1000 > file.$i.txt
done
mkdir emptydir
Run Code Online (Sandbox Code Playgroud)

您将获得一个名为testcase并在此目录中的目录10个文件和一个目录

emptydir  file.1.txt  file.10.txt file.2.txt  file.3.txt  file.4.txt  file.5.txt  file.6.txt  file.7.txt  file.8.txt  file.9.txt
Run Code Online (Sandbox Code Playgroud)

每个文件包含1000行随机字符串,某些行仅包含数字

现在运行命令

find testcase -type f -print | xargs grep -H '^[0-9]*$' | cut -d: -f 2 | sort -nr | head -1
Run Code Online (Sandbox Code Playgroud)

并且您将获得每个文件中最大数字的行,例如:42.(当然,这可以更有效地完成,这仅用于演示)

分解:

find testcase -type f -print将打印每一个普通的文件,因此,LIST(只有降低到文件).输出继电器:

testcase/file.1.txt
testcase/file.10.txt
testcase/file.2.txt
testcase/file.3.txt
testcase/file.4.txt
testcase/file.5.txt
testcase/file.6.txt
testcase/file.7.txt
testcase/file.8.txt
testcase/file.9.txt
Run Code Online (Sandbox Code Playgroud)

xargs grep -H '^[0-9]*$'MAP将运行grep从一个表中每个文件的命令.grep通常用作过滤器,例如:command | grep,但现在(使用xargs)将输入(文件名)更改为(仅包含数字的行).输出,很多行如:

testcase/file.1.txt:1
testcase/file.1.txt:8
....
testcase/file.9.txt:4
testcase/file.9.txt:5
Run Code Online (Sandbox Code Playgroud)

行结构:filename colon number只需要数字,因此调用纯过滤器,从每行中删除文件名cut -d: -f2.它输出许多行,如:

1
8
...
4
5
Run Code Online (Sandbox Code Playgroud)

现在减少(获得最大数量),sort -nr排序所有数字的数字和反向顺序(desc),所以它的输出如下:

42
18
9
9
...
0
0
Run Code Online (Sandbox Code Playgroud)

head -1打印第一行(最大数字).

当然,你可以写自己的列表/过滤器/地图/缩小功能,直接与bash编程结构(循环,条件等),或者你可以使用任何茂盛的脚本语言一样perl,特殊的语言,如awk,sed"语言",或dc(RPN)等等.

有一个特殊的过滤命令,如:

list | filter_command cut -d: -f 2
Run Code Online (Sandbox Code Playgroud)

很简单不需要,因为你可以直接使用

list | cut
Run Code Online (Sandbox Code Playgroud)


kon*_*box 2

您可以执行awkfilter功能reduce

筛选:

awk 'NR % 2 { $0 = $0 " [EVEN]" } 1'
Run Code Online (Sandbox Code Playgroud)

减少:

awk '{ p = p + $0 } END { print p }'
Run Code Online (Sandbox Code Playgroud)