Відповіді:
Додавання до сімейства рішень :-).
duplicator.sh:
for i; do echo -n "$i $i "; done; echo
Зробіть виконуваним і тепер:
$ ./duplicator.sh dog cat bird whale
dog dog cat cat bird bird whale whale
Як варіант оболонки, наприклад, для повторного використання в сценарії:
duplicator() {
for i; do echo -n "$i $i "; done; echo
}
який можна запустити безпосередньо там, де визначено як
duplicator dog cat bird whale
Ви можете використовувати sed:
sed -r 's/(\S+)/\1 \1/g' filename
Якщо ви хочете зберегти зміни у файлі на місці, скажіть:
sed -i -r 's/(\S+)/\1 \1/g' filename
Ви також можете використовувати perl:
perl -M5.10.0 -ne 'say join " ", map{$_, $_} split " ";' filename
(Додати -iопцію для збереження змін у файлі на місці.)
Або, як пропонує тердон :
perl -M5.10.0 -ane 'say join " ", map{$_, $_} @F;' filename
Цитуючи perlvar:
@FМасив
@Fмістить поля кожного рядка, зчитуваного при включенні режиму автоспліт. Дивіться perlrun для-aвимикача. Цей масив є специфічним для пакета, і йому потрібно оголосити або надати повне ім'я пакета, якщо він не є основним пакетом під час роботи підstrict 'vars'.
sed -r 's/\S+/& &/g'.
-a:perl -M5.10.0 -ane 'say join " ", map{$_, $_} @F;'
Що це було б без awk/gawkвідповіді:
$ awk '{ for(i=1;i<=NF+1;i+=1/2) { printf("%s ",$i); }}' <<<"dog cat bird whale"
dog dog cat cat bird bird whale whale
Якщо важливий завершальний новий рядок:
$ awk '{ for(i=1;i<=NF+1;i+=1/2) { printf("%s ",$i); }} END{print ""}' <<<"dog cat bird whale"
for(i=1;i<=NF;++i) printf "%s %s ",$i,$i;ІМХО коротший і легший для читання.
s="dog cat bird wale"
ss=$( tr ' ' '\n' <<< "$s" | sed p | tr '\n' ' ' )
echo "$ss"
dog dog cat cat bird bird wale wale
sed -n 'p;p'- я вважав, що це прозоріше щодо того, що це робиться.
Якщо у вас є рядок у змінній, скажімо foo="dog cat bird whale", ви можете зробити:
Чистий баш:
$ echo "$foo" | (read a b c d && echo "$a $a $b $b $c $c $d $d")
dog dog cat cat bird bird whale whale
Пояснення: Дужки необхідні , так що readі echoвідбувається в тому ж подоболочки і , отже , можуть спільно використовувати змінні. Без них echoпросто надрукували б порожній рядок.
основні:
$ join -j 5 -o 1.1,1.1,1.2,1.2,1.3,1.3,1.4,1.4 <(echo $foo) <(echo)
dog dog cat cat bird bird whale whale
Пояснення:-o прапор joinдозволяє встановити формат виведення. Тут я говорю це надрукувати 1-е поле 1-го файлу ( 1.1), а потім 2-е поле 1-го файлу ( 1.2) тощо. Таким чином, кожне поле 1-го файлу друкується двічі. Однак joinпризначений для об'єднання двох вхідних рядків у загальному полі. Отже, я також передаю йому порожній рядок ( <(echo)), а потім ігнорую його. У -jнаборах З'єднати поле, встановивши його на той , який не існує (5 - й) призводить joinдо друку всієї лінії.
Якщо вам не байдуже пробіл або порядок введення, ви можете зробити це
$ paste <(echo $foo) <(echo $foo)
dog cat bird wale dog cat bird walePerl 1:
$ echo $foo | perl -lane 'push @k, $_,$_ for @F; print "@k"'
dog dog cat cat bird bird whale whale
Пояснення:
-l: adds a newline to each print call (among other things)
-a: turns on field splitting, fields are saved as @F
-n: process input line by line
-e: give a script as a command line parameter.
Сценарій, наведений вище, збереже кожне поле (з @F) двічі в масиві @kі потім надрукує @k. Якщо вам не потрібен новий рядок, ви можете спростити його
$ echo $foo | perl -ane 'print " $_ $_" for @F'Perl 2:
$ echo $foo | perl -0040 -pne 'print "$_"' | paste - -
dog dog cat cat bird bird whale whale
Пояснення:-0 опція встановлює вхідний роздільник записів (як шістнадцяткове або вісімкове число, см тут для перетворення). Тут я встановлюю його на восьмикутник, 040який є пробілом. В -pмарці perlдрук кожного входу «лінія» і з тих пір ми встановили роздільник в простір, лінії тепер визначаються пробілами, тому кожне поле друкуються двічі.
awk:
$ echo $foo | awk '{for(i=1;i<=NF;i++){$i=$i" "$i;} 1;}'
dog dog cat cat bird bird whale whale
Пояснення: NF це кількість полів, тому сценарій вище проходить через кожне поле і додає його до себе. Після цього ми друкуємо рядок ( 1;це просто скорочення для друку).
Тепер для pythonвідповіді:
З командного рядка:
$ python -c "import sys; s=sys.argv[1:]; print(' '.join(j for i in zip(s,s)for j in i));" dog cat bird whale
З stdin:
$ python -c "s=input().split(); print(' '.join(j for i in zip(s,s)for j in i));" <<<"dog cat bird whale"
Результат в обох випадках:
dog dog cat cat bird bird whale whale
Інший підхід, який також використовує лише bash вбудовані
$ string="dog cat bird whale"
$ twix() { while [[ ! -z $1 ]]; do printf "%s %s " $1 $1; shift; done; }
$ twix $string
dog dog cat cat bird bird whale whale
Я не бачу жодних переваг порівняно з головною відповіддю, просто щоб показати дещо інший спосіб, який може бути краще підходить для деяких цілей.
echoтакож оболонка, вбудована в Bash (тест type echo).