ฉันมีสตริงเช่น: dog cat bird whale
และฉันต้องการที่จะได้รับ dog dog cat cat bird bird whale whale
คำทั้งหมดอยู่ในบรรทัดเดียวกัน ความคิดใด ๆ
ฉันมีสตริงเช่น: dog cat bird whale
และฉันต้องการที่จะได้รับ dog dog cat cat bird bird whale whale
คำทั้งหมดอยู่ในบรรทัดเดียวกัน ความคิดใด ๆ
คำตอบ:
การเพิ่มไปยังตระกูลของโซลูชัน :-)
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
ตัวเลือกเพื่อบันทึกการเปลี่ยนแปลงในไฟล์แบบแทนที่)
หรือตามคำแนะนำของterdon :
perl -M5.10.0 -ane 'say join " ", map{$_, $_} @F;' filename
ข้อความจากperlvar
:
@F
อาร์เรย์
@F
มีฟิลด์ของแต่ละบรรทัดที่อ่านเมื่อเปิดโหมด autosplit ดู 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;
ทั้งสั้นและอ่านง่ายกว่า 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'
- ฉันคิดว่ามันโปร่งใสมากขึ้นเกี่ยวกับสิ่งที่ทำ
หากคุณมีสตริงอยู่ในตัวแปร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
เกิดขึ้นใน subshell เดียวกันและดังนั้นจึงสามารถแบ่งปันตัวแปร หากไม่มีพวกเขาecho
ก็จะพิมพ์บรรทัดว่างเปล่า
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
คำอธิบาย:-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 wale
Perl 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
over-the-top เล็กน้อย แต่haskell
คำตอบ:
$ ghc -e "getLine >>= putStrLn . unwords . (concatMap $ replicate 2) . words" <<<"dog cat bird whale"
dog dog cat cat bird bird whale whale
อีกวิธีหนึ่งโดยใช้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
ฉันไม่เห็นประโยชน์ใด ๆ เมื่อเปรียบเทียบกับคำตอบยอดนิยมเพียงเพื่อแสดงวิธีที่แตกต่างออกไปเล็กน้อยซึ่งอาจเหมาะกว่าสำหรับวัตถุประสงค์บางอย่าง
echo
ยังเป็นตัวเชลล์ใน Bash (ทดสอบtype echo
)