Повторите каждую строку несколько раз


17

Хотелось бы, чтобы каждая строка в файле повторялась фиксированное количество раз.

например, каждая строка повторяется четыре раза:

a
b
c

будет выглядеть так:

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

Я провел некоторый поиск, и есть много вопросов и ответов, в том числе и в обратном порядке, например, объединение дублирующих строк в одну строку и, возможно, несколько о дублировании строк путем их повторной печати.

Это было бы легко сделать в C, но хотелось бы знать больше о нативных командах, чтобы мне не приходилось постоянно прибегать к подобным одноразовым выбрасываниям.

Ответы:


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
awk«ы forне нуждается в фигурные скобки , если есть только одна команда , чтобы повторить. И perlпроще , если вы используете foreachцикл: for$i(0..3){print}.
manatwork

4
Альтернативные Perl: perl -ne 'print(($_)x4)'. Кроме того, вы должны цитировать $line(в эхо) в вашей версии Bash.
Дероберт

В моем случае мне нужны были оконечные строки Windows. как видно здесь можно достичь сBEGIN { ORS="\r\n" }
Красный горох

34

Интересно, превращается ли это в матч по гольфу?

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

Объяснение:

pКоманда sed должна напечатать текущую строку. Поведение по умолчанию состоит в том, чтобы напечатать текущую строку непосредственно перед переходом к следующей строке (поэтому sed должен -nпозволить вам отключить ее). У некоторых старых версий нет точки с запятой (я думаю), поэтому возможно, вам придетсяsed -e p -e p -e p

Awk работает с condition {action}парами. Если действие опущено, по умолчанию печатается текущая строка, если условие возвращает true. Awk, как и многие C-подобные языки, воспринимается 1как истина. (Для полноты, если условие опущено, действие будет выполнено для каждой записи.)

Многие функции perl используют преимущества переменной «default». Этот однострочник эквивалентен (на 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, если это так, вы выигрываете :) Что именно делает 1в awk? Сокращения для print $0?
Тердон

3
Операторы Awk состоят из условия и блока, либо являются необязательными, но они должны присутствовать. Условием по умолчанию является 1(true); блок по умолчанию эквивалентен {print}. Таким образом, оператор 1будет означать печать текущей строки buffer ( {print}). ( {print}и {print $0}в основном такие же, Qed.)
Arcege

Я никогда не слышал о sedтом, чтобы точка с запятой не использовалась как терминатор команд; есть ли такая вещь?
Wildcard


4

Вы можете сделать это без необходимости sed, perlили awk.

$ 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 i in `cat sample.txt` ; do seq 1 3 | xargs -i -- echo $i ; done
a
a
a
b
b
b
c
c
c
в то время как цикл
$ while read i; do seq 1 2| xargs -i -- echo $i;done < sample.txt
a
a
b
b
c
c

Я думаю, что версия цикла for будет прерываться на любых строках, содержащих пробелы, поэтому цикл while следует отдавать предпочтение. В противном случае +1, так как я пристрастился к решениям оболочки.
evilsoup

@evilsoup - да, кто-то еще упомянул это и в коде, который я разместил в другом Q & A. Я думаю, что это главное преимущество while over для цикла while, который терпим к разделителю $ IFS и будет разбиваться на конце строки, тогда как for разделяется на $ IFS.
SLM

1

Используя чисто оболочку:

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

Кто-нибудь знает, как сделать да рассматривать --helpкак строку вместо опции? [рассмотрим случай, когда lineесть --helpили другой вариант]
user176581

да,yes -- --help
don_crissti

Использование yesи headозначает, что это не «чисто оболочка»
Гленн Джекман

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 раза.


1

Ответ @potong не работает с пустыми строками, замена \+на *должна исправить это:

sed 'h;:a;s/[^\n]*/&/4;t;G;ba' file
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.