如何使用多行文本获取两个变量的公共行?

如何使用多行文本获取两个变量的公共行?

我有我所获得的域名的逐行列表

for domain in $(nginx -qT | grep -E "^[[:space:]]*server_name" | grep -Ev "^[[:space:]]*#" | sed 's/^[ \t]*//' | sed 's/server_name //g' | tr -d \; | grep -Ev "^_$" | sort | uniq); do echo $domain; done

来自 Nginx 配置。


清晰可见:

for domain in $(
            nginx -qT |
            grep -E "^[[:space:]]*server_name" |
            grep -Ev "^[[:space:]]*#" |
            sed 's/^[ \t]*//' |
            sed 's/server_name //g' |
            tr -d \; |
            grep -Ev "^_$" |
            sort |
            uniq
        ); do
    echo $domain;
done

我的目录中还有几个配置文件,/etc/nginx/conf.d/名称为domain.conf.

我只想从第二个列表中的配置文件描述的第一个列表中提取域。

我可以做什么来合并这两个列表并从最终列表中提取唯一域,仅保留两个列表包含的域?

我列出的第二个清单

for directory in $(grep -ir "include" /etc/nginx/nginx.conf | grep -Ev "^[[:space:]]*#" | grep -v "fastcgi_params\|mime.types" | sed 's/;//g' | grep -o "/.*"); do ls $directory; done

我想在 Bash 脚本中使用这些东西,以便列表保留为变量值而不是文件。我也尝试过使用comm命令,但由于变量它不起作用。

答案1

您可以使用流程替代特点在于bash

进程替换允许使用文件名引用进程的输入或输出。它采取以下形式

<(list)

或者

>(list) 

过程列表异步运行,其输入或输出显示为文件名。该文件名作为扩展结果作为参数传递给当前命令。 [...]如果<(list)使用该形式,则应读取作为参数传递的文件以获得列表的输出。

因此,如果您有两个变量,您可以对它们的内容进行排序并将它们作为 Process Substitution 传递给命令comm

comm -12 <(sort <<< "$VAR1" ) <(sort <<< "$VAR2")

例如,假设我想找到 0 到 12 之间所有可被 2 和 3 整除的数字:

$ VAR1=$(seq 0 2 12)
$ VAR2=$(seq 0 3 12)
$ comm -12 <(sort <<< "$VAR1" ) <(sort <<< "$VAR2")
0
12
6

答案2

根据 @aviro 的回答,结果查询如下所示:

    for directory in $(
        grep -ir "include" /etc/nginx/nginx.conf | 
        grep -Ev "^[[:space:]]*#" | 
        grep -v "fastcgi_params\|mime.types" | 
        sed 's/;//g' | 
        grep -o "/.*" | 
        sed 's/\.conf//g'
    );

        do
            ls $directory | 
            xargs -n 1 basename | 
            sed 's/\.conf//g'; 
        done

相关内容