【发布时间】:2019-08-09 17:11:36
【问题描述】:
我有一个输入文件,每行有 ~100 行和 ~100 个字段。每个字段代表一个正值或负值。我希望打印 $1 后跟每行中的正 或 负字段。每行的正负场数是随机的。
样本输入
0 x 9 8 7 -1 -2 -3
2 x 7 6 -2 -3 -4 -5
4 x 4 3 2 1 -6 -7
想要的输出
积极的
0 9 8 7
2 7 6
4 4 3 2 1
否定
0 -1 -2 -3
2 -2 -3 -4 -5
4 -6 -7
上下文和尝试
上面的输出打印 $1,后跟与 $1 在同一行的剩余字段中的正值或负值。
我尝试的当前代码(对于正值,从我输入的第 6 行开始):
awk 'NR>5{for(i=3; i<=NF; i++) if ( $i > 0 ) print $1, $i}' input > output
这工作正常,除了我打印输出如下:
0 9
0 8
0 7
2 7
2 6
4 4
4 3
4 2
4 1
我也试过了:
awk 'BEGIN {ORS="\t"} NR>5 {print $1} {for(i=3;i<=NF;i++) if ( $i > 0 && i <= NF} {print $i}}' input > output
但是我从不移动到输出中的新行。如果我通过一些 'else if (i = NF) {ORS=...}' 条件将 ORS 改回 \n,那么它将在新行上打印每个 i 的所有字段输出,就像 BEGIN 语句没有效果一样。
问题
我如何告诉 awk 打印 $1,然后将同一输入行的所有其他输出打印到同一输出行,然后在输出中前进 1 个新行并为下一个输入行重复该过程?
谢谢。
回应 Tiw 的回答
我尝试为我的两个文件循环执行此操作:
for j in 1 2; do
positive=ofile.p0
negative=ofile.m0
awk 'NR>5{
printf $1>"positive";
printf $1>"negative";
for(i=3;i<=NF;i++)
if($i~/[-+]?[0-9]+/)
if ($i>0) printf OFS $i>"positive";
else if($i<0) printf OFS $i>"negative";
print "">"positive";
print "">"negative";
}'ofile.0$j
mv positive $positive$j
mv negative $negative$j
done
但它挂起。编辑:Tiw 的答案用 printf 中的 %s 更新。它适用于此更改。
【问题讨论】:
-
输出到不同的文件。
-
@Blaisem,不断地+值和-值都来了,但是为什么有些行打印为+而有些为-?你能解释一下吗?
-
@RavinderSingh13 我的目标是将输入分为正值和负值。我想要一个包含原始输入的输出,但只有具有正值的字段。第二个输出还包含原始输入,但仅包含具有负值的字段。我计划使用 awk 代码来分隔正值,并使用第二个 awk 代码来分隔负值。这有帮助吗?谢谢。
-
@Blaisem.. Perl 解决方案适合你吗?..
-
0应该被认为是正面的还是负面的,或者根本不打印?
标签: awk