Jawaban:
Menambah keluarga solusi :-).
duplicator.sh
:
for i; do echo -n "$i $i "; done; echo
Jadikan dapat dieksekusi, dan sekarang:
$ ./duplicator.sh dog cat bird whale
dog dog cat cat bird bird whale whale
Atau sebagai fungsi shell, mis. Agar dapat digunakan kembali dalam skrip:
duplicator() {
for i; do echo -n "$i $i "; done; echo
}
yang kemudian dapat dijalankan langsung di mana didefinisikan sebagai
duplicator dog cat bird whale
Anda bisa menggunakan sed
:
sed -r 's/(\S+)/\1 \1/g' filename
Jika Anda ingin menyimpan perubahan ke file di tempat, katakan:
sed -i -r 's/(\S+)/\1 \1/g' filename
Anda juga bisa menggunakan perl
:
perl -M5.10.0 -ne 'say join " ", map{$_, $_} split " ";' filename
(Tambahkan -i
opsi untuk menyimpan perubahan ke file di tempat.)
Atau, seperti yang disarankan oleh terdon :
perl -M5.10.0 -ane 'say join " ", map{$_, $_} @F;' filename
Mengutip dari perlvar
:
@F
Array
@F
berisi bidang setiap baris yang dibaca ketika mode autosplit dihidupkan. Lihat perlrun untuk-a
sakelar. Array ini khusus untuk paket, dan harus dideklarasikan atau diberi nama paket lengkap jika tidak dalam paket utama saat dijalankanstrict 'vars'
.
sed -r 's/\S+/& &/g'
.
-a
:perl -M5.10.0 -ane 'say join " ", map{$_, $_} @F;'
Apa ini tanpa awk/gawk
jawaban:
$ 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
Jika penghentian baris baru penting:
$ 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;
keduanya lebih pendek dan lebih mudah dibaca, IMHO.
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'
- saya pikir itu lebih transparan tentang apa yang dilakukannya.
Jika Anda memiliki string dalam suatu variabel, katakanlah foo="dog cat bird whale"
, Anda bisa melakukan:
Pesta murni:
$ echo "$foo" | (read a b c d && echo "$a $a $b $b $c $c $d $d")
dog dog cat cat bird bird whale whale
Penjelasan: Tanda kurung diperlukan agar read
dan echo
terjadi dalam subkulit yang sama dan karenanya dapat berbagi variabel. Tanpa mereka, echo
hanya akan mencetak garis kosong.
coreutils:
$ 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
Penjelasan: The -o
Bendera join
memungkinkan Anda untuk mengatur format output. Di sini, saya mengatakannya untuk mencetak bidang 1 file 1 ( 1.1
), diikuti oleh bidang 2 file 1 ( 1.2
) dll. Dengan begitu setiap bidang file 1 dicetak dua kali. Namun, join
dirancang untuk, well, bergabung dengan dua jalur input pada bidang yang sama. Jadi, saya juga memberikannya baris kosong ( <(echo)
) dan kemudian mengabaikannya. The -j
set bergabung lapangan, pengaturan untuk salah satu yang tidak ada (ke-5) penyebabjoin
untuk mencetak seluruh baris.
Jika Anda tidak peduli dengan spasi putih atau urutan input, Anda bisa melakukannya
$ paste <(echo $foo) <(echo $foo)
dog cat bird wale dog cat bird wale
Perl 1:
$ echo $foo | perl -lane 'push @k, $_,$_ for @F; print "@k"'
dog dog cat cat bird bird whale whale
Penjelasan:
-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.
Script di atas akan menyimpan setiap bidang (dari @F
) dua kali dalam array @k
dan kemudian mencetak @k
. Jika Anda tidak memerlukan trailing newline, Anda dapat menyederhanakannya
$ echo $foo | perl -ane 'print " $_ $_" for @F'
Perl 2:
$ echo $foo | perl -0040 -pne 'print "$_"' | paste - -
dog dog cat cat bird bird whale whale
Penjelasan: The -0
option menetapkan pemisah record input (sebagai heksadesimal atau nomor oktal, lihat di sini untuk konversi). Di sini, saya mengaturnya ke oktal 040
yang merupakan ruang. The -p
merek perl
mencetak setiap masukan "line" dan karena kami telah menetapkan rekor pemisah ruang, garis sekarang didefinisikan oleh spasi, sehingga setiap bidang dicetak dua kali.
awk
:
$ echo $foo | awk '{for(i=1;i<=NF;i++){$i=$i" "$i;} 1;}'
dog dog cat cat bird bird whale whale
Penjelasan: NF
adalah jumlah bidang, jadi skrip di atas melewati setiap bidang dan menambahkannya sendiri. Setelah selesai, kami mencetak baris ( 1;
hanya singkatan untuk cetak).
Sekarang untuk python
jawabannya:
Dari baris perintah:
$ 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
Dari stdin:
$ python -c "s=input().split(); print(' '.join(j for i in zip(s,s)for j in i));" <<<"dog cat bird whale"
Hasilnya dalam kedua kasus:
dog dog cat cat bird bird whale whale
Sedikit berlebihan, tetapi sebuah haskell
jawaban:
$ ghc -e "getLine >>= putStrLn . unwords . (concatMap $ replicate 2) . words" <<<"dog cat bird whale"
dog dog cat cat bird bird whale whale
Pendekatan lain, juga hanya menggunakan bash builtins
$ 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
Saya tidak melihat manfaat apa pun dibandingkan dengan jawaban teratas, hanya untuk menunjukkan cara yang sedikit berbeda, yang mungkin lebih cocok untuk beberapa tujuan.
echo
juga merupakan builtin shell di Bash (test type echo
).