SED的典型应用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SED的典型应用相关的知识,希望对你有一定的参考价值。
参考技术ASED的典型用法:Sed接受一个或多个编辑命令,并且每读入一行后就依次应用这些命令。
当读入第一行输入后,sed对其应用所有的命令,然后将结果输出。接着再读入第二行输入,对其应用所有的命令……并重复这个过程。上一个例子中sed由标准输入设备(即命令解释器,通常是以管道输入的形式)获得输入。在命令行给出一个或多个文件名作为参数时,这些文件取代标准输入设备成为sed的输入。sed的输出将被送到标准输出(显示器)。因此:
cat filename | sed '10q' # 使用管道输入
sed '10q' filename # 同样效果,但不使用管道输入
sed '10q' filename > newfile # 将输出转移(重定向)到磁盘上
要了解sed命令的使用说明,包括如何通过脚本文件(而非从命令行)来使用这些命令。
要发掘sed的潜力,则必须对“正则表达式”有足够的理解 。
Unix系统所提供的手册页(“man”)也会有所帮助(试一下这些命令“man sed”、“man regexp”,或者看“man ed”中关于正则表达式的部分),但手册提供的信息比较“抽象”——这也是它一直为人所诟病的。不过,它本来就不是用来教初学者如何使用sed或正则表达式的教材,而只是为那些熟悉这些工具的人提供的一些文本参考。
从 ini 文件的某些部分读取某些键(sed/awk?)
【中文标题】从 ini 文件的某些部分读取某些键(sed/awk?)【英文标题】:Read certain key from certain section of ini file (sed/awk ?) 【发布时间】:2014-04-28 07:39:19 【问题描述】:我需要从具有典型结构的 ini 文件中检索键的值:
[abcd]
key1=a
key2=b
[efgh]
key1=c
key2=d
[hijk]
key1=e
key2=f
键名在不同部分重复,并且部分的命名/顺序不一致。我怎样才能从 efgh 找到 key1?如果我使用 grep,我会找到所有 key1(而且我不知道这些部分的顺序)。
我怀疑 sed 或 awk 可以做到这一点,但我找不到它......
【问题讨论】:
【参考方案1】:这可能是一个开始:
awk -F'=' -v section="[efgh]" -v k="key1" '
$0==section f=1; next # Enable a flag when the line is like your section
/\[/ f=0; next # For any lines with [ disable the flag
f && $1==k print $0 # If flag is set and first field is the key print key=value
' ini.file
您传递了两个变量,section
和 k
。 section
需要包含您要查看的部分。 k
应该包含您试图为其获取价值的 key
。
在[efgh]
部分下查找key1
的值:
$ awk -F'=' -v section="[efgh]" -v k="key1" '
$0==section f=1; next
/\[/ f=0; next
f && $1==k print $0
' ini.file
key1=c
在[hijk]
部分下查找key2
的值:
$ awk -F'=' -v section="[hijk]" -v k="key2" '
$0==section f=1; next
/\[/ f=0; next
f && $1==k print $0
' ini.file
key2=f
【讨论】:
@Michelle 你能详细说明什么不起作用吗?错误?什么都没找到?在您的问题中发布相关数据集。这只是打印值。你想要整个key=value
对吗?【参考方案2】:
使用 sed
sed -r ':a;$!N;ba;s/.*\[efgh\][^[]*(key1=[^\n]*).*/\1/' file
key1=c
另一种方式
sed -nr '/\[efgh\]/,/\[//key1/p' file
【讨论】:
像这样吞食整个文件可能不是一个好主意。 好建议,第二个怎么样?我是根据@Guru 的想法制作的。 抱怨 Perl 不可读的人应该尝试 sed ... :-)。但是,第二个示例中的反斜杠迷宫完美地满足了我的要求!【参考方案3】:一种方式:
sed -n '/\[efgh\]/,/\[.*\]/p' file | awk -F= '/key2/print $2'
使用 sed,提取从 [efgh] 到下一个 [....] 模式的行范围。使用awk,在这行范围内搜索key2,得到值。
【讨论】:
你实际上可以通过sed -nr '/\[efgh\]/,/\[.*\]//key1/s/(.*)=(.*)/\2/p' file
避免 awk
【参考方案4】:
这些sed
单线为我工作,无耻地从github:thomedes/ini.sed 复制
# List all [sections] of a .INI file
sed -n 's/^[ \t]*\[\(.*\)\].*/\1/p'
# Read KEY from [SECTION]
sed -n '/^[ \t]*\[SECTION\]/,/\[/s/^[ \t]*KEY[ \t]*=[ \t]*//p'
# Read all values from SECTION in a clean KEY=VALUE form
sed -n '/^[ \t]*\[SECTION\]/,/\[/s/^[ \t]*\([^#; \t][^ \t=]*\).*=[ \t]*\(.*\)/\1=\2/p'
# examples:
sed -n 's/^[ \t]*\[\(.*\)\].*/\1/p' /etc/samba/smb.conf
sed -n '/^[ \t]*\[global\]/,/\[/s/^[ \t]*workgroup[ \t]*=[ \t]*//p' /etc/samba/smb.conf
sed -n '/^[ \t]*\[global\]/,/\[/s/^[ \t]*\([^#; \t][^ \t=]*\).*=[ \t]*\(.*\)/\1=\2/p' /etc/samba/smb.conf
【讨论】:
【参考方案5】:这可能对你有用(GNU sed):
sed -rn '/^\[/h;d;G;s/^key1=(.*)\n\[efgh\]$/\1/p' file
复制节标题并将其与节正文进行比较。
【讨论】:
以上是关于SED的典型应用的主要内容,如果未能解决你的问题,请参考以下文章