Bash:我如何偷看并保存stdin的第一行

时间:2014-10-31 14:49:26

标签: bash

我有一个设置文件,当cateded具有格式

NAME1.1 NAME2.1 NAME3.1 KEY1 VALUE1.1 KEY2 VALUE2.1
NAME1.2 NAME2.2 NAME3.2 KEY1 VALUE1.2 KEY2 VALUE2.2
...
NAME1.N NAME2.N NAME3.N KEY1 VALUE1.N KEY2 VALUE2.N

并且读取键值对文本引用繁琐,所以我认为处理脚本是有序的,所以我写了这个

#!/bin/bash
cat "$@" \
    | head -n1 \
    | awk '{printf("NAME1 NAME2 NAME3 ");for(i=4;i<NF;i+=2){printf("%s ",$i)}printf("\n")}'

cat "$@" \
    |awk '{printf("%s %s %s ",$1,$2,$3);for(i=5;i<=NF;i+=2){printf("%s ",$i)}printf("\n")}'

正如您所看到的,我正在播放文件两次只是为了获取标题行,因此我可以获取值并将其格式化为

NAME1   NAME2   NAME3   KEY1     KEY2
NAME1.1 NAME2.1 NAME3.1 VALUE1.1 VALUE2.1
NAME1.2 NAME2.2 NAME3.2 VALUE1.2 VALUE2.2
...
NAME1.N NAME2.N NAME3.N VALUE1.N VALUE2.N

有没有一种好方法可以窥视和复制第一行,这样我就可以保存它?

我试过像这样的单线眼

( cat *.all_my_files \
  | tee >( head -n1 | awk '{printf("NAME1 NAME2 NAME3 ");for(i=4;i<NF;i+=2){printf("%s ",$i)}printf("\n")}' ) \
  | awk '{printf("%s %s %s ",$1,$2,$3);for(i=5;i<=NF;i+=2){printf("%s ",$i)}printf("\n")}' \
  ) | column -t

但是当stdouts中的任何一个完成给我一个不确定的输出量时,这似乎退出

2 个答案:

答案 0 :(得分:3)

似乎您可以立即将所有文件传递给awk并为第一条记录执行特殊操作:

awk 'NR==1{printf("NAME1 NAME2 NAME3 ");for(i=4;i<NF;i+=2){printf("%s ",$i)}print ""}
     {printf("%s %s %s ",$1,$2,$3);for(i=5;i<=NF;i+=2){printf("%s ",$i)}' "$@"

第一个块仅在NR==1时执行,这仅对第一个文件的第一个记录为真。将对所有记录执行另一个块,包括第一个。

答案 1 :(得分:0)

就我而言,我最终想调用的程序不同于awk。

这是一种hack,它似乎没有效率或可移植性,但是如果您想在shell中严格执行此操作,则可以使用read来抓取第一行,然后使用子shell进行组合第一行包含标准输入的其余部分,然后将其通过管道传递给另一个命令。

read -r FIRST_LINE
COL_COUNT="$(echo "$FIRST_LINE" | awk '{print NF; exit}')"

if [[ "$COL_COUNT" -eq "1" ]]; then
  # Do one column things
else
  # Do multi column column things
fi

(echo "$FIRST_LINE" && cat -) | callYourCommand