我希望在目录下的以下文件中获取端口号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
。最后一个测试将区分单个匹配和不匹配(模式保持未扩展)。
awk
grep
可以完成、 和 的工作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
在打印所需的文本时以零退出状态退出,这会导致循环终止。