我想读取文件中的指定行iptables。我想阅读以:并以空间。
文件 iptables
# Generated by iptables 04:13:50 2015
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp -m tcp --sport http --dport 1024: -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport https --dport 1024: -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport webcache --dport 1024: -m state --state ESTABLISHED -j ACCEPT
COMIT
# Completed on Mon Dec 04:13:50 2015
我的输出应该是这样。
INPUT
FORWARD
OUTPUT
我怎样才能做到这一点?我正在思考sed
,IFS
但我不知道该怎么做。
我得到的输出看起来像这样
13:50
INPUT
0]
FORWARD
0]
OUTPUT
0]
13:50
执行后:
grep -Po ':\K[^ ]*' file
我想省略13:50
and0]
以及其他相关的东西。
我的目标是只有在链的名称。
答案1
我建议使用grep
:
grep -Po '^ *:\K[^ ]*' file
解释:
-P
: 使用perl兼容的正则表达式-o
:只打印匹配的部分\K
:剪切到目前为止匹配的所有内容[^ ]*
:匹配除空格之外的所有内容零次或多次
输出:
INPUT
FORWARD
OUTPUT
答案2
其他sed
:
sed -ne's/^:\([[:upper:]]*\).* $/\1/p' <in >out
s///
此命令尝试对每个输入行进行一次替换。除非成功,否则不会输出-n
任何内容。p
所以/regexp/
必须匹配一行,并且替换必须在rint任何内容s///
之前发生,因为它唯一的rint 命令是sed
p
p
旗帜关于s///
替代声明。
为了匹配输入行,必须首先匹配行首的:
冒号,紧随其后的是零个或多个大小写字母字符,然后是零个或多个任何其他类型的字符,最后必须是 at行尾至少有一个空格。^
*
[[:upper:]]
*
.
$
当它匹配时,子组[[:upper:]]
中引用的 -char序列将用于替换保存在.\(
\)
\1
但这不适用于您的示例输入,因为您的示例以空格开头,以空格结尾。适用于您的示例的正则表达式:
sed -ne's/^ *:\([[:upper:]]*\).*/\1/p'
大部分是相同的,但不是在行尾寻找确定的空格,而是在头部寻找任意数量的空格。
INPUT
FORWARD
OUTPUT
答案3
为此,请执行以下操作sed
:
sed -n ' # -n do not print lines to output by default
/^:.* $/ { # address lines beginning with colon, ending with space
s/^:// # remove colon at beginning of line
s/ .*// # remove first space and everything following
p # print the edited line
}
'