用空格/字符替换只有一个字段的行

时间:2018-09-26 05:42:10

标签: awk sed

我想在一个长表中做两件事,下面给出一个示例块。

(1)将所有具有单个字段的行(例如包含102和103的行)替换为字符(例如,我使用的字符为“ m”)

(2)如果连续两行中都有m(即,在上面(1)之后的每一行中都将有一个“ m”,而不是102和103),然后删除其中一行,以便

这看起来像

-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
102
103
 -84.4994,   18.0632
-84.2222,   18.1732

此(1)之后

-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
m
m
-84.4994,   18.0632
-84.2222,   18.1732

以及(2)之后的

-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
m
-84.4994,   18.0632
-84.2222,   18.1732

7 个答案:

答案 0 :(得分:2)

您可以尝试以下awk命令:

awk -F"," '(NF==1){if(a){} else {print "m"; a=1}}(NF>1){a=0; print $0}' inputFileName

(NF==1)条件检查该行是否只有一个字段。 (这是需要更换的地方。)

如果上一行已被替换,则变量a等于1

答案 1 :(得分:2)

awk '{ if (length($0) < 4) {print "Char";} else {print $0}}' filename | tr '\n' '\r' | sed -e 's,Char\rChar,bla,g' | tr '\r' '\n'

看看这对您有用吗?

  1. 文件名是输入,
  2. awk检查长度并相应打印
  3. sed将两个连续的字符替换为Char

答案 2 :(得分:2)

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

sed '/^\S*$/{s//m/;n;//d}' file

如果一行为空白或包含单个字段,请用m替换当前行,然后打印该行并在下一行补充图案空间。如果该行还是空白或包含单个字段,则将其删除。

此解决方案可满足两条连续的此类生产线(如果有两条或更多条生产线),则还有另外两种解决方案:

sed -n '/^\S*$/{s//m/p;:a;n;//ba};p' file

或者:

sed '/^\S*$/!{x;z;x;b};x;s/^/m/;/^m$/p;x;d' file

答案 3 :(得分:2)

$ awk 'NF==1{if (!p) print "m"; p=1; next} {print; p=0}' file
-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
m
 -84.4994,   18.0632
-84.2222,   18.1732

答案 4 :(得分:1)

问题的第一部分可以使用来解决:

awk '(NF==1){print "m"; next}1'

由于适用于(condition){action}对,因此我们将以上理解为:

  1. 检查是否只有一个字段,如果有,请打印m并移至下一条记录/行。
  2. 如果上述条件不适用,我们将转到下一个动作1,这对1{print $0}来说是非常短的形式。即打印行。 (请参见Awk gsub and the mysterious "1"

如果以前我们只有一个字段,则问题的第二部分需要跟踪。让我们用标记f

来跟踪它
awk '(NF==1){ if (!f) print "m"; f=1; next}{f=0}1'

假设如果前一行具有单个字段,则f设置为ONE,否则设置为零(并且知道在f=0开始时),那么我们将上述理解为:

  1. 检查是否只有一个字段,如果有,如果上一行没有一个字段,则打印m。然后设置f=1并移至下一行/记录
  2. 如果上一个操作不成立,请将f设置为值0
  3. 并打印行1

中,您可以这样做:

sed '$!N;s/\n[^,]*$/\nm/;/^[^,]*\n[^,]*$/!P;D'

哪个:

  1. $!N,如果不在EOF处,请将下一行附加到模式缓冲区中
  2. s/\n[^,]*$/\nm/如果仅包含单个字段(我假设字段以逗号分隔),则将模式缓冲区中的最后一行替换为单个字母m
  3. /^[^,]*\n[^,]*$/!P如果图案缓冲区包含只有一行字段的两行,请勿打印图案缓冲区。
  4. D删除所有内容,直到模式缓冲区中的第一个\n

这是Sed one-liners explained

中示例69的一个小改编

答案 5 :(得分:1)

另一个awk

$ awk -F, 'NF==1 {p=1; next} 
           p     {print "m"; p=0}1; 
           END   {if(p) print "m"}' file

-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
m
 -84.4994,   18.0632
-84.2222,   18.1732

答案 6 :(得分:1)

尽管未标记Perl,但它在这种情况下效果最佳。试试这个。

$ cat januka.txt
-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
102
103
 -84.4994,   18.0632
-84.2222,   18.1732
$ perl -0777 -pe ' s/^\S+$/m/mg; s/(^m\n){2,}/$1/mg ' januka.txt
-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
m
 -84.4994,   18.0632
-84.2222,   18.1732
$ 

甚至可以缩短为

$ perl -0777 -pe ' s/(^\S+\n){2,}/m\n/mg ' januka.txt
-84.7363,   18.0227
-84.4994,   18.0632
-84.2222,   18.1732
m
 -84.4994,   18.0632
-84.2222,   18.1732
$