我有以下文件示例
more somefile
param=a b c d e f g z x w
# param=a b c d e f g z x w
我需要使用sed创建以下内容(如果可能,应该是一行):
a b c d e f g z x w
”(如grep -w)并在成功时给出退出状态像......那样的东西。
sed "/^ *#/b; /\<param\>/" ....
答案 0 :(得分:0)
第一个术语在开头删除带有'#'的行。 目前尚不清楚为什么你想要两个术语匹配参数和尾随材料(为什么不匹配?)。 目前尚不清楚是否要打印匹配的行。 并且不清楚您是否可以从sed获取退出状态,指示是否有任何行与模式匹配 - 您会被告知是否能够执行脚本并打开所有文件,但这就是全部。有了所有这些警告,那么:
sed -n '/^#/d;/param=a b c d e f g z x w/p' somefile
这会打印匹配的行,忽略(-n
)那些不匹配的行。
如果'='符号周围有空格,您可以修改搜索模式以允许:
sed -n '/^#/d;/param *= *a b c d e f g z x w/p' somefile
目前尚不清楚“价值”部分内部的间距是否至关重要;如果不是,那么您可以使用适当的“*
”(空格,空格,星号;标记编辑器再次努力工作)条款以允许可变空格。
但是,如果您想要类似grep的状态,则可能需要使用grep
。正如我所指出的那样 - sed
没有返回'找到模式'或'未找到模式'的状态,因为这不是它所关注的。
如果你真的希望sed
做两个匹配,那么你必须进入分组操作,这些操作不再是单行脚本。
sed -n '/^#/d;/param/{
/a b c d e f g z x w/p
}' somefile
这说:
注意:如上所述,第一个模式匹配也会找到'xyz = param'和'parameter = a b c';如果这不是您想要的,请适当修改模式。第二种模式也会发现'g h i a b c d ... x w';如果那不是你想要的,你必须适当地修改它。
我认为你最好用sed来删除注释和空行,然后使用你的grep序列来查找你的值。您必须使用GNU grep
;其他计算机(Solaris,AIX,HP-UX等)上的POSIX标准版grep
不支持-w
选项。即使使用grep序列,您也无法区分如下行:
param=a b c d e f g z x w
a b c d e f g z x w=param
此外,这些都不允许在参数名称之前使用前导空格,并且它们都不允许使用制表符而不是空格。此外,必须有怀疑的余地,即使参数名称是固定的,价值也可能随时变化;将其转换为可用的shell脚本(调用sed或grep或两者)会增加要考虑的细节。
这导致:
if [ $# -lt 3 ]; then echo "Usage: $0 name value file [...]" 1>&2; exit; fi
name=$1
value=$2
shift 2
sed -n -e '/^#/d' -e "/ *$name *= *$value *$/p" "$@"
现在,如果这个脚本被称为paramfinder
,我可以写:
paramfinder param 'a b c d e f g z x w' somefile
我也可以写:
paramfinder param '.*a b c d *e f g *z x w.*' somefile
请注意,我已将正则表达式元字符传递给值中的sed脚本。
请注意,如果我通过它将会中断:
paramfinder passwordfile /etc/passwd somefile
那是因为“/ etc / passwd”中的斜杠会破坏正则表达式匹配。
根据您的实际要求(是家庭作业还是生产问题 - 以及它必须具备的健壮性),您可以考虑转移到Perl某处(或Python或您选择的其他类似脚本语言)。
答案 1 :(得分:0)
您可以使用嵌套花括号在AND
中执行sed
个条件:
sed -n '/\<param\>/ { /^[[:space:]]*#/ ! { /\<a \+b \+c \+d \+e \+f ... \>/ p}}'
这表示如果符合以下行匹配:
AND
不会(!
)以任何空格后的注释字符开头AND
有一个“单词”,由一个或多个空格分隔的字符序列组成要测试是否成功,您需要查看结果是否为非空字符串:
if [[ -n $(sed ...) ]]