逐列连接 X 号。时间的

Column wise concatenation X no. of time

我有一个文件,其中包含一些由换行符分隔的字符串,in.txt:

$ echo -e 'a\nb\nc' > in.txt
$ cat in.txt 
a
b
c

而且我需要为 in.txt 列中的每一行将特定的固定值连接到文件中,所以首先我做了:

$ yes '0.0' | head -n 3
0.0
0.0
0.0

然后paste它:

$ yes '0.0' | head -n 3 > 0s
$ paste in.txt 0s 
 a  0.0
 b  0.0
 c  0.0

问题是我如何执行按列连接 X 号。 of times? 假设 X 是 100,000 ,手动输入 paste in.txt 0s 0s 0s ... 是不可行的。

这样的事情怎么样

paste in.txt \`printf '0s %.0s' {1..$X}\`

我从 https://superuser.com/questions/86340/linux-command-to-repeat-a-string-n-times

得到了 printf 部分

你也可以像下面这样使用for循环;

paste in.txt $(for i in {1..3}; do echo '0s'; done)

paste in.txt <(for i in {1..X}; do echo $(yes 0.0 | head -3); done)

paste in.txt <(for i in {1..3}; do echo $(yes 1.1 | head -$(wc -l in.txt| awk '{print }')); done)

例如:

user@host:/tmp$ paste in.txt <(for i in {1..3}; do echo $(yes 1.1 | head -3); done)
a   1.1 1.1 1.1
b   1.1 1.1 1.1
c   1.1 1.1 1.1

Sed 解决方案

您可以使用 printf 生成您想要的字符串,并使用 sed:

替换每行的末尾
$ num=5
$ sed 's/$/'"$(for ((i=0; i<num; ++i)); do printf '\t%s' '0.0'; done)"'/' in.txt
a       0.0     0.0     0.0     0.0     0.0
b       0.0     0.0     0.0     0.0     0.0
c       0.0     0.0     0.0     0.0     0.0

分配给 num 的值是要添加到文件中的列数。

替换将每一行结尾 ($) 替换为此命令的输出:

for (( i=0; i < num; ++i )); do
    printf '\t%s' '0.0'
done

如果您不介意使用 seq,这可以简化为

sed 's/$/'"$(printf '\t0.0%.0s' $(seq 1 $num))"'/' in.txt

即替换中的命令是一行

printf '\t0.0%.0s' $(seq 1 $num)

有关如何使用各种工具在 Bash 中重复字符串的许多选项,请参阅问题 How can I repeat a character in bash?

awk解决方案

这里以num作为要添加的列数,并使用制表符作为字段分隔符:

awk -v num=5 -v OFS="\t" '{for (i=1; i<=num; ++i) $(NF+1) = "0.0"}1' in.txt

for 循环将 0.0 分配给最后一个字段,num 次; 1 打印行。

我会将问题分为两部分。首先,创建一个包含所需尺寸和内容的制表符分隔文件(R 行乘 C 列,每个单元格包含字符串 F)。然后,将生成的文件粘贴到现有文件中:

R=$(wc -l < in.txt)   # num rows to generate, in this case same num lines as input
C=100000              # num columns to generate
F=0.0                 # fixed value

paste in.txt <(yes $F | head -$(($R * $C)) | pr -t$C -s$'\t')

对于给定的样本输入,C=5 列,我得到:

a       0.0     0.0     0.0     0.0     0.0
b       0.0     0.0     0.0     0.0     0.0
c       0.0     0.0     0.0     0.0     0.0

从里到外打破管道:

  • yes $F 生成固定值流
  • head -$(($R * $C)) 在我们生成了我们需要的所有单元格后切断 yes 流
  • pr -t$C -s$'\t' 将流旋转成制表符分隔的 table 具有我们想要的列数
  • <() 将以上所有内容放入一个(本质上)临时文件
  • paste in.txt <() 将两个文件按行相邻