我想基于匹配模式,用另一个文件中的行替换文件中的某些行。 我想替换以" rolOccupant"开头的每一行。找到后 "#SBD_ING_USER"包含文件x
中内容的空行档案x
roleOccupant: uid1
roleOccupant: uid2
roleOccupant: uid45
roleOccupant: uid80
输入文件
# SDB_ING_USER
objectClass: organizationalRole
objectClass: top
cn: SDB_ING_USER
description: SDB Ing User Role
roleOccupant: uid1
roleOccupant: uid7
roleOccupant: uid67
# SDB_REGISTERY_USER:
objectClass: organizationalRole
objectClass: top
cn: SDB_REGISTRY_USER
description: SDB Registry Admin Role
roleOccupant: uid2
roleOccupant: uid34
roleOccupant: uid15
OUTPUT文件
# SDB_ING_USER
objectClass: organizationalRole
objectClass: top
cn: SDB_ING_USER
description: SDB Ing User Role
roleOccupant: uid1
roleOccupant: uid2
roleOccupant: uid45
roleOccupant: uid80
# SDB_REGISTERY_USER:
objectClass: organizationalRole
objectClass: top
cn: SDB_REGISTRY_USER
description: SDB Registry Admin Role
roleOccupant: uid2
roleOccupant: uid34
roleOccupant: uid15
答案 0 :(得分:2)
awk 单线
awk -v RS= -v ORS='\n\n' 'NR==FNR{a=$0;next} /SDB_ING_USER/{sub(/roleOccupant.*/,""); $0=$0 a} 1' fileX file
-v RS=
将空行设置为记录分隔符
FNR==NR{a=a$0; next}
:这会将您的File X
内容存储在变量a
/# SDB_ING_USER/ {gsub(/roleOccupant.*/,a ORS)}
:迭代Input file
if记录包含# SDB_ING_USER
,然后将所有行从roleOccupant
替换为记录结尾a ORS
换句话说a "\n"
输出
# SDB_ING_USER
objectClass: organizationalRole
objectClass: top
cn: SDB_ING_USER
description: SDB Ing User Role
roleOccupant: uid1
roleOccupant: uid2
roleOccupant: uid45
roleOccupant: uid80
# SDB_REGISTERY_USER:
objectClass: organizationalRole
objectClass: top
cn: SDB_REGISTRY_USER
description: SDB Registry Admin Role
roleOccupant: uid2
roleOccupant: uid34
roleOccupant: uid15
答案 1 :(得分:0)
使用awk
<强>一衬垫:强>
awk 'FNR==NR{r=(r!=""?r RS:"")$0;next}/# SDB_ING_USER/{u=1}u && /^roleOccupant:/{next}u && !NF{print r; u=""}1;END{if(u)print r}' file1 file2
更好的可读性:
awk '
FNR==NR{
r=(r!=""?r RS:"")$0;
next
}
/# SDB_ING_USER/{
u=1
}
u && /^roleOccupant:/{
next
}
u && !NF{
print r;
u=""
}1
END{
if(u)print r
}
' file1 file2
<强>解释强>
FNR==NR{r=(r!=""?r RS:"")$0;next}
此块我们只读file1
并保存变量r
中的file1行,由记录分隔符RS
分隔,FNR==NR
将是如果awk
读取第一个文件,则为true。
/# SDB_ING_USER/{u=1}
如果file2
中的行包含/..../
中的正则表达式,则设置变量u=1
u && /^roleOccupant:/{next}
如果设置了变量u
,并且行以roleOccupant
开头,请跳过此行,然后从file2
u && !NF{print r; u=""}
如果设置了变量u
,则!NF
表示空行(NF
不会记录记录中的字段,NF=0
表示空行,!0
为1
,这是真实状态),然后打印变量r
,并使变量u
}1
1执行默认操作,即打印当前上下文中的当前记录/行/行,此默认操作仅在上述语句中未跳过记录时才会执行。
<强>文件1:强>
$ cat file1
roleOccupant: uid1
roleOccupant: uid2
roleOccupant: uid45
roleOccupant: uid80
<强> file2的:强>
$ cat file2
# SDB_ING_USER
objectClass: organizationalRole
objectClass: top
cn: SDB_ING_USER
description: SDB Ing User Role
roleOccupant: uid1
roleOccupant: uid7
roleOccupant: uid67
# SDB_REGISTERY_USER:
objectClass: organizationalRole
objectClass: top
cn: SDB_REGISTRY_USER
description: SDB Registry Admin Role
roleOccupant: uid2
roleOccupant: uid34
roleOccupant: uid15
<强>输出:强>
$ awk 'FNR==NR{r=(r!=""?r RS:"")$0;next}/# SDB_ING_USER/{u=1}u && /^roleOccupant:/{next}u && !NF{print r; u=""}1;END{if(u)print r}' file1 file2
# SDB_ING_USER
objectClass: organizationalRole
objectClass: top
cn: SDB_ING_USER
description: SDB Ing User Role
roleOccupant: uid1
roleOccupant: uid2
roleOccupant: uid45
roleOccupant: uid80
# SDB_REGISTERY_USER:
objectClass: organizationalRole
objectClass: top
cn: SDB_REGISTRY_USER
description: SDB Registry Admin Role
roleOccupant: uid2
roleOccupant: uid34
roleOccupant: uid15
答案 2 :(得分:0)
如果输入文件是sdb.txt
而文件x是x.txt
,我使用sed命令文件cmd.sed
来执行此操作:
sed -f cmd.sed sdb.txt
sed.cmd
:
# Within the section from SDB_ING_USER to a blank line /SDB_ING_USER/,/^$/{ # Delete roleOccupant lines /roleOccupant/d # At the blank line /^$/{ # Read x.txt into the output stream r x.txt # Append a blank line to the output stream a # Delete the blank line from the input stream # (Prevents a blank line before the x.txt content) d } }
这是使用sed命令文件而不是单行sed命令完成的,因为sed r
和a
命令需要换行符,因此尝试使用它们很痛苦单行。(参见下面有关换行的编辑和-e
)
输出:
$ sed -f cmd.sed sdb.txt # SDB_ING_USER objectClass: organizationalRole objectClass: top cn: SDB_ING_USER description: SDB Ing User Role roleOccupant: uid1 roleOccupant: uid2 roleOccupant: uid45 roleOccupant: uid80 # SDB_REGISTERY_USER: objectClass: organizationalRole objectClass: top cn: SDB_REGISTRY_USER description: SDB Registry Admin Role roleOccupant: uid2 roleOccupant: uid34 roleOccupant: uid15
EDIT。看看potong使用e cat
允许将x.txt文件读入模式空间(而不是输出流)并意识到在命令行中你可以使用多个-e
参数来获得有效行单线sed命令中断。
所以这是一个新的单行:
sed -e '/SDB_ING_USER/,/^$/{' -e '/roleOccupant/d' -e '/^$/e cat x.txt' -e '}' sdb.txt
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed '/SDB_ING_USER/,/^\s*$/!b;/roleOccupant/d;/^\s*$/e cat x' file
关注SDB_ING_USER
与下一个空行之间的界限。删除包含字符串roleOccupant
的所有行,并在空行前插入文件x
。