如何在 shell 脚本中的每个 awk 命令中实现回车或换行符,以便每个命令的输出与下一个命令的输出分开?
也许我需要更多说明。我有两个 awk 命令,如下所示:
awk {print $1, $2}
,awk 命令 1,输出:
John Bender
Bohn Jender
Jen Bondher
awk '{print $3, $4}'
,命令 2,输出:
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543
当与 shell 脚本结合使用并与 运行时./<testscript>.sh <textfile>
,命令行显然会输出:
John Bender
Bohn Jender
Jen Bondher
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543
因为我想要 PER awk 命令的换行符附加,所以我希望输出看起来简单如下:
John Bender
Bohn Jender
Jen Bondher
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543
先前尝试附加“\n”导致:
John Bender
Bohn Jender
Jen Bondher
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543
..这当然是不受欢迎的。
答案1
由于您是从 shell 脚本内部运行的,因此只需echo
在每个awk
命令后(即在您想要获得单独输出的命令之间)添加。
echo
添加换行符。例如:
awk '{print $1 $2}' file.txt
echo
awk '{print $3, $4}' file.txt
原始答案:
附加在每个动作printf "\n"
的末尾。awk
{}
printf "\n"
将打印一个换行符。
例子:
% awk '{print $1; printf "\n"}' <<<$'foo bar\nspam egg'
foo
spam
答案2
正因为可以做到这一点,所以可以采取以下替代方法。
带有 NR 和 FNR 变量的 ARGIND
这种方法运行文件两次,并且在第二次运行文件时,它会打印一个换行符,这是通过使用一些有趣的想法实现的。
为了处理相同的文件但提取不同的信息,在命令行上给出两次文件。
我们如何区分何时运行第一个文件(提取字段 $1 和 $2)以及何时运行第二个文件?通过使用
ARGIND
变量。NR
是迄今为止处理的总记录数,是FNR
当前文件中处理的总记录数。对于第一个文件,它们是相同的。什么时候它们会不同?当我们处理第二个文件时。此时我们需要打印换行符,但不知何故阻止它被打印为其他值NR > FNR
。我们举起一个标志(通过标志变量)。
示例输出:
$ awk '!flag && NR>FNR {print "";flag=1} ARGIND==1{print $1,$2}ARGIND==2{print $3,$4}' data.txt data.txt
John Bender
Bohn Jender
Jen Bondher
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543
END 子句的使用
正如 heemayls 答案下的评论中提到的那样,当使用两个单独的 awk 命令时,可以END
在文件处理完成后使用 block 来打印一些内容
$ awk '{print $1,$2}END{print "\n"}' data.txt; awk '{print $3,$4}' data.txt
John Bender
Bohn Jender
Jen Bondher
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543
END 块与关联数组的变体
由于您的 $3 块基本上是一遍又一遍的相同内容(字符串“AGE”),因此您不必存储它,但您可以将 $4 存储到关联数组中。然后在 END 块中,您可以在打印换行符后迭代存储的值。
$ awk '{print $1,$2;age[i++]=$4}END{print"";for(var in age) print "AGE",age[var]}' data.txt
John Bender
Bohn Jender
Jen Bondher
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543