在shell上使用linux很新。
我想减少用于提取以下数据的管道数量。
V 190917135635Z 1005 unknown /C=DE/ST=City/L=City/O=something/OU=Somewhat/CN=someserver.com/emailAddress=test@toast.com
我的目标是将以下值放在单独的文件中
190917135635 someserver.com
我现在使用的命令相当长,已通过管道传递,看起来像这样
grep -v '^R' $file | awk '{print $2, $6}' | awk -F'[=|/]' '{print $1, $3}' | awk '{print $1, $3}' | awk -F 'Z ' '{print $1, $2}' > sdata.txt
(文件包含以'R'开头的其他行,因此我排除了我的grep中的行)
这是合法的方式吗?
有没有办法在较短的命令中得到这个?
非常感谢!
答案 0 :(得分:1)
看起来您的某些数据字段用于创建SSL证书,因此许多字段可能包含SPACES,即城市,组织名称等。这就是为什么您需要许多awk行(???)的原因。这是一种可以帮助您克服这些问题的方法。因此,目标不是通过转换现有的代码逻辑,而是通过搜索子字符串CN=
并获取其对应的值来查找域名。
awk '
!/^R/{
start = index($0, "CN=")+3
end = index(substr($0, start), "/")
domain = end ? substr($0, start, end-1) : substr($0, start)
print $2, domain
}
' file.txt
位置:
index()
查找子字符串CN=
的起始位置,+3
将是域名的起始点/
,以获取该域的末尾位置。如果在行尾,则不会有/
,因此end
将为'0'CN=
获得子字符串substr($0, start, end-1)
与下一个'/'之间的域名,或者使用substr($0, start)
获得行尾。简短版本:
awk '!/^R/{s=index($0, "CN=")+3; e=index(substr($0, s), "/"); print $2, substr($0, s, e ? e-1 : 253)}' file.txt
其中253
是可能的最长域名,可能足以满足您的需求。
更新:
实际上,使用match()
会容易得多,但要点是相同的:
awk '!/^R/{if(match($0, "/CN=([^/]*)")) print $2, substr($0, RSTART+4, RLENGTH-4)}' file.txt
答案 1 :(得分:1)
另一个awk。使用match
查找CN条目,并使用substr
提取CN条目以供print
打印(如果存在)。
$ awk '!/^R/{
print $2,
(match($0,/CN=[^/]+/)?substr($0,RSTART+3,RLENGTH-3):"") # 3==length("CN=")
}' file
输出:
190917135635Z someserver.com
答案 2 :(得分:1)
如果这样:
$ awk -F'[[:space:]/=]+' '!/^R/{print $2+0, $16}' file
190917135635 someserver.com
不是您所需要的,然后更新您的问题以阐明您的要求并提供更真实的示例输入/输出。
答案 3 :(得分:0)
编辑: :严格考虑OP的Input_file与所示示例相同。看到OP的样本后,可以尝试跟随。
awk -F"[ =/Z]" '!/^R/{print $8,$37}' Input_file
对于FUN :),如果有人想尝试OP的方法,那么我们可以尝试遵循。
awk '
!/^R/{
val=$2 OFS $5
split(val,array,"[ /Z]")
val1=array[1] OFS array[9] OFS array[10]
split(val1,array1,"[ =]")
print array1[1],array1[3]
}
' Input_file
答案 4 :(得分:0)
使用GNU sed
:
sed -E -n '/^R/d; s/^[A-Za-z]\s+([0-9]+)\s+[0-9]+\s+.*\/CN=(.*)\/.*/\1 \2/p' input_file > new_file
答案 5 :(得分:0)
您在第二个$6
命令中使用awk
,这意味着与示例数据不同,您的 5th 列内部可能有空间 s 如图所示,它也正在提取CN=
部分(CNAME?)。
因此,这是一种更兼容且更精确的sed
方式,它不需要GNU sed:
sed -n -e '/^R/!{' -e 's|^[^[:space:]]*[[:space:]]*\([^[:space:]Z][^[:space:]Z]*\).*/CN=\([^/][^/]*\).*|\1 \2|p;}'
如果您只想在第二栏中输入数字,并且以数字开头,那么您可以更改为使用该数字:
sed -n -e '/^R/!{' -e 's|^[^[:space:]]*[[:space:]]*\([0-9][0-9]*\).*/CN=\([^/][^/]*\).*|\1 \2|p;}'