每行重复多次


17

希望文件中的每一行重复固定的次数。

例如,每行重复四次:

a
b
c

变成:

a
a
a
a
b
b
b
b
c
c
c
c

我已经进行了一些搜索,沿着反向进行的过程中有很多问题和答案,例如,将重复的行合并为单行,也许还有一些关于通过再次打印将行加倍的问题。

在C语言中这样做很容易,但是我希望我对本机命令有更多的了解,因此我不必一直使用这种一次性的方法。

Answers:


19
  • Perl:

    perl -ne 'for$i(0..3){print}' file

    并且我必须添加由@derobert 发表的评论,因为它很酷:

    perl -ne 'print "$_" x4'
  • awk 和变体:

    awk '{for(i=0;i<4;i++)print}' file
  • bash

    while read line; do for i in {1..4}; do echo "$line"; done; done < file

1
awkfor如果只有一个命令重复没有需要括号。而perl更简单,如果你使用的foreach循环:for$i(0..3){print}
manatwork

4
替代的perl :perl -ne 'print(($_)x4)'。同样,您应该$line在bash版本中引用(以回显形式)。
derobert

就我而言,我需要Windows行尾。如此处所示,可以实现BEGIN { ORS="\r\n" }
红豌豆2015年

34

我想知道这是否会变成一场高尔夫比赛:

sed 'p;p;p' 
awk '1;1;1;1' 
perl -lpE 'say;say;say'   # if Paul McCartney and Michael Jackson were hackers...

说明:

sed的p命令是打印当前行。默认行为是在移至下一行之前打印当前行(这就是sed必须-n允许您将其关闭的原因)。一些较老的sed没有分号(我认为),因此您可能必须这样做sed -e p -e p -e p

Awk可condition {action}成对使用。如果省略该动作,则默认为在条件返回true时打印当前行。与许多类似C的语言一样,Awk被1视为真实。(为完整起见,如果省略条件,将对每个记录执行该操作。)

许多perl函数都利用“默认”变量。这种单行代码等效于(在perl 5.16上):

$ perl -MO=Deparse -lpE 'say;say;say'
BEGIN { $/ = "\n"; $\ = "\n"; }
use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    say $_;
    say $_;
    say $_;
}
continue {
    die "-p destination: $!\n" unless print $_;
}

1
+1,如果是,那您就赢了:) 1awk 到底在做什么?简写为print $0
terdon

3
Awk语句由一个条件和一个块组成,它们都是可选的,但必须存在一个。默认条件是1(true); 默认块等效于{print}。因此,该语句1意味着要打印当前的行缓冲区({print})。({print}{print $0}qed基本相同)
Arcege

我从未听说过sed不支持将分号用作命令终止符;真的有这样的事吗?
通配符


4

你可以这样做,而不需要sedperlawk

$ for i in `cat <file>` ; do seq <#> <#> | xargs -i -- echo $i ; done

或使用while循环:

$ while read i ; do seq <#> <#> | xargs -i -- echo $i ; done < <file>

例子

for循环
$ for i in `cat sample.txt` ; do seq 1 3 | xargs -i -- echo $i ; done
a
a
a
b
b
b
c
c
c
while循环
$ while read i; do seq 1 2| xargs -i -- echo $i;done < sample.txt
a
a
b
b
c
c

我认为for循环版本将在包含空格的任何行上中断,因此应首选while循环。否则,请+1,因为我是shell解决方案的傻瓜。
evilsoup

@evilsoup-是的,有人在我在另一个问答中发布的一些代码中也提到了这一点。我认为这是while over for的主要优势,while循环可以容忍$ IFS分隔符,并且可以在行尾拆分,而for可以拆分$ IFS。
slm

1

使用纯壳:

repeats=4
while read line; do yes $line|head --lines=$repeats; done < infile > outfile

有人知道如何使yes视为--help字符串而不是选项吗?[考虑以下情况line is --help或其他选项的情况]
user176581

是的yes -- --help
don_crissti 2015年

使用yeshead表示这不是“纯壳”
glenn jackman

1

这可能对您有用(GNU sed):

sed 'h;:a;s/[^\n]\+/&/4;t;G;ba' file

将重复每行4次。

或者,如果您喜欢:

sed 'h;:a;s/\n/&/3;t;G;ba' file

您在每行重复3次以上。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.