1

如果有一个文本文件包含以下内容:

1 2 3 4 5 6

如何用空格等​​字符替换某个字符串(例如 4)之前的所有内容?

1 2 3 4 5 6(输入)

    4 5 6   (OUTPUT)
4

3 回答 3

4

这可能对您有用(GNU sed):

sed '/4/{:a;/^ *4/!s/[^ ]/ /;ta}' file

或者:

sed 's/4/\n&/;T;h;s/[^\n]/ /g;G;s/\n.*\n//' file

或者:

awk '/4/{while(!/^ *4/)sub(/[^ ]/," ")}1' file

或者:

awk '/4/{sub(/4/,"\n&");h=$0;gsub(/[^\n]/," ");$0=$0 h;sub(/\n.*\n/,"")}1' file
于 2013-09-28T13:19:41.417 回答
3

你现在真的进入了一些神秘的 sed 魔法。保持简单,只需使用清晰的函数名称、变量和可理解的结构在 awk 中编写:

$ cat file
1 2 3 4 5 6    
$ awk 'match($0,/4/){
    pre=substr($0,1,RSTART-1)
    gsub(/./," ",pre)
    print pre substr($0,RSTART)
}' file
      4 5 6

sed 是用于在单行上进行简单替换的出色工具,但对于其他任何事情,只需使用 awk。如果您使用超过 s、g 和 p(带 -n)的 sed 语言结构,那么您使用的工具是错误的。一旦 awk 被发明,几乎所有其他 sed 语言结构都在 1976 年左右过时了。

如果您在一年后回来增强此脚本以执行不同的操作,例如在行尾打印一个计数,现在许多字符已替换为空格,您是否愿意尝试理解然后修改它:

sed 's/\(4\)/\n\1/;Tq;h;s/^[^\n]*\n//;x;s/\n.*//;s/./ /g;G;s/\n//;:q'

还是上面的 awk 脚本?在 awk 脚本中进行的调整只是添加和打印一个变量(cnt如下):

awk 'match($0,/4/){
    pre=substr($0,1,RSTART-1)
    cnt=gsub(/./," ",pre)
    print pre substr($0,RSTART), cnt
}' file

我预计,要让 sed 脚本执行此操作,需要 3 只山羊、一个血月和蝙蝠侠符号。

于 2013-09-28T12:49:08.473 回答
1
$ echo -e '1 2 3 4 5 6\n7 8 9 0 1 2'|
> sed 's/4/\n&/;T;h;s/^[^\n]*\n//;x;s/\n.*//;s/./ /g;G;s/\n//'
      4 5 6
7 8 9 0 1 2
$

解释:

s/4/\n&/;T        # places "\n" marker before "4", quits otherwise
h;s/^[^\n]*\n//;x # puts "4 5 6" into hold space
s/\n.*//          # keeps only "1 2 3 "
s/./ /g           # replaces each char with space
G;s/\n//          # appends "4 5 6" from hold space
于 2013-09-28T04:29:55.123 回答