Awk 将只有一个字段的行替换为空格/char

Awk 将只有一个字段的行替换为空格/char,awk,sed,Awk,Sed,我想在一个长表中做两件事,下面给出了一个示例块 1将所有具有单个字段的行(例如,包含102和103的行)替换为字符(例如,我使用的字符是m) 2如果在两个连续的行中有m,即,不是102和103,则在1之后的每行中都有m,然后删除其中一行,以便 这看起来像 -84.7363, 18.0227 -84.4994, 18.0632 -84.2222, 18.1732 102 103 -84.4994, 18.0632 -84.2222, 18.1732 这是1点以后的事 -84

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

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

2如果在两个连续的行中有m,即,不是102和103,则在1之后的每行中都有m,然后删除其中一行,以便

这看起来像

-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

您可以尝试此awk命令:

awk -F"," '(NF==1){if(a){} else {print "m"; a=1}}(NF>1){a=0; print $0}' inputFileName
NF==1条件检查该行是否只有一个字段。这是需要更换的地方

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

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

filename是输入, awk检查长度并相应打印 sed将两个连续字符替换为字符
您问题的第一部分可以通过以下方式解决:

由于使用条件{action}对,我们理解为:

检查是否只有一个字段,如果只有,请打印m并移动到下一条记录/行。 如果上述条件不适用,我们将进入下一个操作,即1,这是对1{print$0}的一个非常简短的形式。即打印该行。看见 如果之前我们只有一个字段,那么问题的第二部分需要跟踪。让我们用国旗f来跟踪它

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

检查是否只有一个字段,如果是,如果前一行没有一个字段,请打印m。然后设置f=1并移动到下一行/记录 如果上一个操作不起作用,请将f设置为值0 然后打印第1行。 在这方面,你可以做:

sed '$!N;s/\n[^,]*$/\nm/;/^[^,]*\n[^,]*$/!P;D'
其中包括:

$!N如果不是在EOF,则将下一行追加到模式缓冲区 s/\n[^,]*$/\nm/如果模式缓冲区中的最后一行只包含一个字段,则将其替换为一个字母m。我假设字段是逗号分隔的 /^[^,]*\n[^,]*$/!P如果模式缓冲区包含只有一个字段的两行,则不要打印模式缓冲区。 D删除模式缓冲区中第一个\n之前的所有内容。
这是对

中示例69的一个小修改,这可能适用于GNU-sed:

sed '/^\S*$/{s//m/;n;//d}' file
如果一行为空或包含单个字段,请将当前行替换为m,然后打印该行并用下一行填充图案空间。如果该行也为空或包含单个字段,请将其删除

此解决方案适用于两条连续的此类线路,如果有两条或更多,这里有两个或更多的解决方案:

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

另一个awk


尽管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
$

不清楚,请您在您的帖子中添加更清晰的详细信息,然后通知我们。评论不是为了提供信息,请使用适当的详细信息更新您的帖子,然后通知我们。如果行中没有条目,则此操作将失败。感谢您提供此解决方案!这将不起作用,因为awk没有任何输入文件,因此将以/dev/stdin作为输入。此外,$行永远不会被替换,因为它包含在单引号中。另外,如果awk能够做到这一点,那么为什么要使用while循环呢?awk设计为逐行读取文件。否则,我没有意见。通过一些修复,这可能会起作用。最后一点,如果您想使用while循环,请使用while read-r行;做完成sed '/^\S*$/!{x;z;x;b};x;s/^/m/;/^m$/p;x;d' file
$ 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
$ 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
$ 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
$