结合awk和sed匹配行并替换字符

时间:2013-12-29 07:08:28

标签: regex sed awk

我试图匹配第一个字母,在这个例子中" B"和第二列" 2"。找到匹配项时,用空格替换字符[38-41]。

以下是我试图修改的数据:

A1234A123 1 2 12345.12345 1234.1234.112341234

B1234A123 2 2 12345.12345 1234.1234.112341234

A1234A123 2 2 12345.12345 1234.1234.112341234

我可以使用以下方法将条件与awk匹配:

awk '/^B/ && $2=="2" {print}' 

我可以使用sed修改sed行:

sed -r 's/^(.{37})(.{4})/\1    /' 

我试图在文件中找到包含两个条件的行,然后修改字符,同时仍然打印不匹配的整行行。你能结合这两个命令来引入某种if / then语句吗?

我试图合并命令,但它编辑了所有行:

awk '/^B/ && $2=="2" {print}' ¦ sed -r 's/^(.{37})(.{4})/\1    /' data

结果数据应如下所示:

A1234A123 1 2 12345.12345 1234.1234.112341234

B1234A123 2 2 12345.12345 1234.1234.1    1234

A1234A123 2 2 12345.12345 1234.1234.112341234

提前致谢。

4 个答案:

答案 0 :(得分:3)

您可以使用单个awk组合这两个命令:

awk '/^B/ && $2=="2"{$0=substr($0, 1, 37) "    " substr($0, 38, 4)} 1' file
A1234A123 1 2 12345.12345 1234.1234.112341234
B1234A123 2 2 12345.12345 1234.1234.1    1234
A1234A123 2 2 12345.12345 1234.1234.112341234

答案 1 :(得分:2)

您可以通过预先添加正则表达式来指示sed仅替换匹配的行(/^B[^ ]* 2/):

sed -r '/^B[^\s]*\s2\s/s/^(.{37}).{4}/\1    /' data

答案 2 :(得分:1)

使用GNU awk:

gawk '/^B/ && $2=="2" {print gensub(/(.{37}).{4}/,"\\1    ","")}' data

答案 3 :(得分:0)

在Gnu Awk第4版中你可以尝试:

gawk 'BEGIN { FIELDWIDTHS = "1 9 1 26 4 20"; OFS="" }
$1=="B" && $3=="2" {
    $5="    "
} 1' file

带输出:

A1234A123 1 2 12345.12345 1234.1234.112341234
B1234A123 2 2 12345.12345 1234.1234.1    1234
A1234A123 2 2 12345.12345 1234.1234.112341234