为每个与glob匹配的文件生成一列

时间:2019-02-06 21:02:56

标签: bash shell unix

我在听起来相对简单的事情上遇到了困难。我有一些带有单个值的数据文件,如下所示:

data1.txt:

[ i for i, row in enumerate(final_vals) if all([ e >= -1 and e <= 1 for e in row ]) ]
#=> [6, 7]

data2.txt

100

data3.txt

200

我还有一个名为header.txt的文件,它是一个包含标题的模板文件,如下所示:

300

我正在尝试将data * .txt文件中的数据添加到Master.txt的最后一行

所需的输出将是这样的:

Data_1    Data2   Data3
-         -       -

我正在积极地工作,所以我不确定从哪里开始。不需要在纯shell中实现,而是使用awk或sed之类的标准UNIX工具是完全合理的。

2 个答案:

答案 0 :(得分:1)

作为本机bash实现:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*) echo "ERROR: Bash 4.0+ needed" >&2; exit 1;; esac

declare -A keys=( )       # define an associative array (a string->string map)
for f in data*.txt; do    # iterate over data*.txt files
  name=${f%.txt}          # for each, remove the ".txt" extension to get our name...
  keys[${name^}]=$(<"$f") # capitalize the first letter, and read the file to get the value
done

{                                       # start a group so we can redirect output just once
  printf '%s\t' "${!keys[@]}"; echo     # first line: keys in our associative array
  printf '%s\t' "${keys[@]//*/-}"; echo # second line: convert values to dashes
  printf '%s\t' "${keys[@]}"; echo      # third line: print the values unmodified
} >>Master.txt                          # all the above with output redirected to Master.txt

这里的大多数魔法是由parameter expansions执行的:

  • ${f%.txt}.txt的末尾开始修剪$f扩展名
  • ${name^}大写$name的首字母
  • "${keys[@]}"扩展为名为keys的数组中的所有值
  • "${keys[@]//*/-}用固定字符串*替换每个键中的-(所有内容)。
  • "${!keys[@]}"扩展为关联数组keys中条目的名称

答案 1 :(得分:1)

paste是关键工具:

#!/bin/bash
exec >>Master.txt
cat header.txt
paste $'-d\n' data1.txt data2.txt data3.txt |
while read line1
do
    read line2
    read line3
    printf '%-10s %-10s %-10s\n' "$line1" "$line2" "$line3"
done