【发布时间】:2014-04-04 21:00:14
【问题描述】:
我不习惯将sed 用于任何事情,我不确定这是否可行。
我需要在文本文件中执行以下操作:
- 查找以“abc”开头的行
- 在所述行的“b”和“c”之间插入“xyz”
- 用新行替换原行
一个巨大警告:如果没有以“abc”开头的行,我需要插入一行,并且必须在以“def”开头的行之前插入。
【问题讨论】:
-
到目前为止您是否尝试过任何代码?
我不习惯将sed 用于任何事情,我不确定这是否可行。
我需要在文本文件中执行以下操作:
一个巨大警告:如果没有以“abc”开头的行,我需要插入一行,并且必须在以“def”开头的行之前插入。
【问题讨论】:
(1) 你的问题的第一部分可以这样写:
sed -i .bak 's/^abc/abxyzc/' input_file
(-i .bak 用于就地编辑,并创建扩展名为“.bak”的备份文件)
(2) 第二部分,在另一行之前插入一行(不包括“abc”缺失的情况),可以这样做:
sed -i .bak 's/^def/NEW_LINE\ndef/' input_file
我认为您不能将“if cond do (1) else do (2)”写成单行。为此编写一个简单的脚本...
【讨论】:
这可能对你有用(GNU sed):
sed -r ':a;$!{N;ba};s/(^|\n)(ab)(c)/\1\2xyz\3/;t;s/(^|\n)(def)/\n\1\2/' file
将文件拖入内存。在行首的ab 和c 之间替换xyz。如果执行此替换,则中断进一步处理。否则,在行首的def 之前替换一个换行符。
【讨论】:
awk '
/^def/ && !inserted {print "abxyzc"; forced = 1}
/^abc/ && !forced {sub(/^abc/,"abxyzc"); inserted = 1}
1
END {if ((!inserted) && (!forced)) print "abxyzc"}
' file > tmp && mv tmp file
如果没有“abc”并且没有“def”,我会在最后打印修改后的“abc”行。您没有指定这种情况。
【讨论】:
sed 会有点复杂。如果您可以使用awk,那么以下应该可以工作。这会对文件进行两次传递。如果它找到/^abc/,它会按照您的要求执行。如果未找到/^abc/,则它会查找/def/ 并在其前一行插入xyz。
awk '
NR==FNR && /^abc/{
found = 1
$0 = substr($0,0,2) "xyz" substr($0,3)
lines[NR] = $0
next
}
NR==FNR {
lines[NR] = $0
next
}
!found && /^def/ {
lines[FNR-1] = lines[FNR-1] "\nabc"
}
END {
for(line=1; line<=FNR; line++)
print lines[line]
}' file{,} > tmp && mv tmp file
【讨论】:
file file 更改为file{,}