问题: ”A" 从 END 部分打印的变量只有最后找到的行而不是所有行
文件1:
pattern .........
irrelevant text
irrelevant text
pattern .........
pattern .........
irrelevant text
awk代码:
awk '{ for (i=1; i<=NR; i++)
if ($i ~ /^pattern/) a+=$0
}
END {print $a}' file1
从 END 部分我只想打印带有图案的行
答案1
您似乎想要收集与特定模式匹配的所有行,然后在最后打印它们。
你可以这样做
awk '/^pattern/ { a[++n] = $0 }
END { for (i = 1; i <= n; ++i) print a[i] }' file
这用作a
数组并将与模式匹配的每一行添加为数组中的新条目。最后,循环迭代 的条目a
并打印每个条目。
如果您想在第一列中查找确切的文字字符串,pattern
而不是针对整行匹配正则表达式,请使用$1 == "pattern"
as 条件。
但是,如果这是全部你想做的,那么使用就更容易
awk '/^pattern/' file
或者,如果您想匹配pattern
第一列中的文字字符串,
awk '$1 == "pattern"' file
这将为与模式匹配的每一行调用默认操作,或者pattern
如果您使用第二个变体,则将其包含为第一列。 “默认操作”是打印该行。
在 中awk
,将是一个算术运算,它将当前行a += $0
的值递增,解释为数字。a
要将 line 作为字符串连接到变量a
,您可以使用a = a $0
, 或者如果您想在附加的字符串之前a = a ORS $0
插入换行符( 的默认值)。ORS
但我相信这些都不是您想要在这里做的。
答案2
您的代码有几个问题:
您想要访问文件的所有行以测试匹配模式,但您是在一个规则块 (
{ ... }
) 中执行此操作。但是所有规则都会被处理对于文件的每一行,并且在这样的规则中,您只能访问当前处理的行的内容。代码{ for (i=1; i<=NR; i++) if ($i ~ /^pattern/) a+=$0 }
因此会尝试(对于文件的所有行,因为它前面没有条件)来测试领域数字 1 到
NR
- 哪里NR
是文件中当前行的行号,不是当前行的字段数NF
,而是尝试追加整个当前行a
每次发生这种情况时都指向变量。如果模式确实只能出现在正则表达式所暗示的行的开头(由于锚),这可能不会弄乱结果,^
但至少效率极低。在尝试将当前行附加到 时
a
,您编写a+=$0
然而,只有当该行(或至少第一个空格分隔的字段)可以被正确解释为数字时,这才是明确定义的,在这种情况下,这
a
将是仅包含/开头的所有行上的数字之和文件中出现的单个数字。如果没有一行可以被解释为数字,则a
最后的值为“0”。在
END
块中,您声明print $a
然而,这将打印字段编号
a
当前行的内容,而不是变量的内容a
。然而,由于您的变量a
是“0”(如第 2 点中所述),因此这将指整个当前行(也称为$0
)。并且由于对块中字段编号的引用END
始终引用文件的最后一行(由于文件末尾缺少“当前”行),因此此语句将不可避免地打印文件的整个最后一行,而不会打印其他内容。
由于您似乎只对打印与特定模式匹配的行感兴趣,因此使用grep
专用于此类任务的工具可能会更容易。
答案3
如果您只想打印第一个字段为 的所有行pattern
,则无需将内容存储在内存中,您可以只打印找到的每一行:
awk '$1=="pattern"' file
甚至
grep -w '^pattern' file
相反,如果您想打印每一行任何该行的字段是pattern
,使用:
awk '{ for(i=1; i<=NF; i++){ if($i=="pattern"){ print; next}}}' file
或者,如果您只是寻找字段值的情况开始,pattern
但之后可以有其他字符(这是您的代码所尝试的),如果您只想要第一个字段,请使用它:
awk '$1~/^pattern/' file
这适用于任何领域:
awk '{ for(i=1; i<=NF; i++){ if($i~/^pattern/){ print; next}}}' file
答案4
如果我正确理解你的问题,你想要连接所有与 匹配的行^pattern
,所以这将满足你的需要:
echo $(grep '^pattern' infile)
awk
与:相同
echo $(awk '/^pattern/' infile)
或awk
仅使用:
awk '/^pattern/{ line = (line? line FS $0: $0) } END{ print line }' infile