提问人:Luca L 提问时间:12/20/2022 更新时间:12/22/2022 访问量:401
awk 命令:如果行不以字符开头,请在行之前删除换行符
awk command: if line doesn't starts with a character remove new line on before line
问:
尝试使用 awk 命令来实现此规则:如果行不以“O|”或“A|”或“S|”开头我想删除 before 行上的换行符
我在输入中有这个文件(输入.txt)
O|field1|field2
O|field1|
field2
A|field1|
field2
S|field1|
field2
O|field1|field2
O|field1|field2
O|field1|
field2
A|field1|
field2
S|field1|
field2
O|field1|field2
我想要这个输出
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
执行此代码
awk '/^O\|/ || /^A\|/ || /^S\|/ {printf "%s", $0; next} 1 {print}' input.txt > output.txt
它返回
O|field1|field2O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2O|field1|field2O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
有人可以帮我吗?
答:
4赞
anubhava
12/20/2022
#1
这应该对你有用:awk
awk -F'|' 'NF==3 && $3 == "" {p = $0; next}
{print (NF == 1 ? p $1 : $0); p = ""}' file
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
3赞
Ed Morton
12/20/2022
#2
像这样测试记录布局的东西可能比测试字段的值更适合你:
$ awk -v RS='([^|]*[|]){2}[^|]*\n' '{$0=RT; gsub(/\n/,""); print}' file
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
上面使用 GNU awk for multi-char RS 将一条记录定义为 3 个以 s 分隔并以换行符结尾的字段,然后在打印之前从每条记录中删除任何换行符。|
3赞
The fourth bird
12/20/2022
#3
您似乎只遇到缺少最后一个字段的问题。
如果 是字段分隔符,您可以检查第 3 个字段是否不为空并打印整行。|
打印上一行加上当前行(如果字段 1 不是)或A
O
S
awk -F'|' '{
if($1 !~ /^[AOS]$/) { print p $0; next }
if ($3!="") print $0
p = $0
}' file
输出
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
4赞
RavinderSingh13
12/20/2022
#4
使用您显示的示例,请尝试以下代码。awk
awk '
BEGIN{FS=OFS="|"}
!/\|/ {
print val,$0
val=""
next
}
$0~/\|$/ && NF==3{
val=$0
next
}
1
' Input_file
1赞
RARE Kpop Manifesto
12/20/2022
#5
{m,g,n}awk NF=NF RS= OFS=\| FS='[|]\n' { g,n}awk NF=NF RS= OFS=\| FS='\\|\n' {m }awk NF=NF RS= OFS=\| FS='\|\n'
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
评论
2赞
The fourth bird
12/20/2022
有趣的解决方案,您能解释一下这是如何工作的吗?做什么,你能把它放在开头吗?NF=NF
1赞
RARE Kpop Manifesto
12/21/2022
@Thefourthbird :与其他人使用的方法相同,但您可以安全地在控制台终端中输入,不加引号。s 按反斜杠的方式接受命令行赋值,而 and 将它们视为主代码中的任何双引号字符串,因此需要双反斜杠,正如您在 的 2 个差异变体中看到的那样。如果你把任何东西放在它的左边,你还必须添加标志前缀,例如.在主代码之后执行此操作允许跳过该部分,但这些部分.....NF = NF
$1=$1
mawk
gawk
nawk
FS
NF=NF
-v
-v OFS=…
1赞
RARE Kpop Manifesto
12/21/2022
.....在所有部分之后(如果有),但在 .设置为空白意味着所有输入块之间没有完全为零长度的空行都会立即得到处理,我只是交换了 和 的角色,并用于修复格式问题。因此,这些解决方案是为自然界中不连续输送的输入而设计的。BEGIN { }
NR == 1
RS
FS
RS
FS + OFS
1赞
RARE Kpop Manifesto
12/21/2022
@Thefourthbird : 实际上是一个有问题的形式::::::::::::::::::::: ::::::::::::::::::: ::::::::::::::::: :::::::::::::::::::::::::::::::: :::::::::::::: :::::::::::::::::::它什么都不打印,因为实际上是一个空字符串,并且驻留在 中。赋值与 doing 相同,这意味着该模式正在将空字符串计算为布尔值,因此没有执行 的默认操作。 修复了该问题,请记住,由于为零,它仍会跳过空行$1 = $1
echo ' abc xyz ' | mawk '$1=$1' FS='[ ]+'
$1
"abc"
$2
$1 = ""
FALSE
{ print }
NF=NF
NF
3赞
karakfa
12/20/2022
#6
另一种解决方案
awk -v RS="" '{gsub("\\|\n","|")}1' file
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
O|field1|field2
O|field1|field2
A|field1|field2
S|field1|field2
O|field1|field2
将文件视为一个长流,并删除管道后面的换行符。
1赞
Walter A
12/21/2022
#7
使用 GNU :sed
sed -rz 's/\|\n([^OAS])/\|\1/g' input.txt
0赞
Martin York
12/22/2022
#8
怎么样:
awk '/^[OAS]\|/ {if (l){print l}l=$0;next} {l=l $0} END {print l}' inputFile
该变量表示我们正在构建的线。l
如果输入以特殊字符开头,则打印(如果它不是空)。否则,开始建立阵容。在处理完所有行以打印出 的最新版本后运行。l
END
l
评论