Grep 正在打印“grep:” - 如何忽略它

Grep 正在打印“grep:” - 如何忽略它

我希望在目录下的以下文件中获取端口号Variable。当文件的端口行为空时,我将被grep:打印出来。有没有办法忽略它,并且不打印任何内容?

if ls $directory/*.domain.*.properties 1>/dev/null 2>&1; then
    port=$(grep "domain.http.listener.port=" $directory/*.domain.*.properties | 
           awk -F "=" 'NR==1{print $NF}' | tr -d "\r")
fi

答案1

domain.http.listener.port=您的代码似乎在多个文件中查找带有 的表达式grep,并且您的awk命令将从该结果的第一行(仅)打印最后一个=分隔字段,然后删除结果中的任何回车符。

不需要ls。您似乎正在使用它来测试文件名通配模式是否$directory/*.domain.*.properties匹配任何内容(也可能拆分空白的值$directory并对这些位执行文件名通配)。

要测试文件名通配模式是否与任何文件名匹配,您可以使用

set -- "$directory"/*.domain.*.properties

(我引用了变量的扩展,directory因为我假设它应该只包含单个目录的名称或路径名),然后是

if [ "$#" -gt 1 ] || [ -e "$1" ]; then ...; fi

set命令设置位置参数($1$2$3等),如果我们得到多个这些参数($#大于 1),则该模式匹配多个事物。此外,如果模式与单个事物匹配,我们会使用 测试该事物是否存在-e。最后一个测试将区分单个匹配和不匹配(模式保持未扩展)。

awkgrep可以完成、 和 的工作tr,因此实际上不需要您拥有的管道:

awk -F '=' '/domain\.http\.listener\.port=/ { sub("\r","", $NF); print $NF; exit }'

我正在转义正则表达式中的点,因为否则它们会匹配任何字符。我只在这里使用sub(),而不是gsub(),因为我假设您想删除行尾的回车符,而不是其他地方。

全部一起:

#!/bin/sh

set -- "$directory"/*.domain.*.properties

if [ "$#" -gt 1 ] || [ -f "$1" ]; then
    awk -F '=' '/domain\.http\.listener\.port=/ { sub("\r","", $NF); print $NF; exit }' "$@"
fi

我将-e测试更改为-f测试,因为在常规文件(或一个符号链接)上运行比在其他任何文件上运行更有意义awk(但如果有多个文件,我不会测试任何文件的文件类型)火柴)。

将扩展到命令中模式设法匹配的"$@"所有名称(单独引用) 。set

您想要包含第一个匹配项的文件的路径名,那么您可以将 修改awk为也打印出特殊变量的内容FILENAME(例如print FILENAME, $NF)。你想要全部匹配项(不仅仅是第一个文件中的第一个匹配项),然后删除exit.

请注意,如果有数百或数千个文件与文件名通配模式匹配(就像您的文件一样),则此解决方案将失败。在这种情况下,您可以执行 shell 循环:

for pathname in "$directory"/*.domain.*.properties; do
    if [ -f "$pathname" ]; then
        awk -F '=' '
            /domain\.http\.listener\.port=/ {
                sub("\r","", $NF); print $NF; found=1; exit
            }
            END { exit !found }' "$pathname" && break
    fi
done

在这里,我选择awk在打印所需的文本时以零退出状态退出,这会导致循环终止。

相关内容