回答:
ソリューションのファミリーに追加:-)。
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
は、自動分割モードがオンになっているときに読み込まれる各行のフィールドが含まれます。-a
スイッチについてはperlrunを参照してください。この配列はパッケージ固有であり、で実行するときにパッケージmainにない場合は、宣言するか完全なパッケージ名を指定する必要があります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"
、次のようにできます。
純粋なbash:
$ 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
、空行を印刷するだけです。
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
)に続いて1番目のファイルの2番目のフィールド(1.2
)などを印刷するように指示しています。そのように、1番目のファイルの各フィールドが2回印刷されます。ただし、共通フィールドの2つの入力行をjoin
結合するように設計されています。そのため、空行()を渡して無視します。セット原因が存在しないもの(第5回)に設定すると、フィールドに参加行全体を印刷します。<(echo)
-j
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
)を配列に2回保存してから@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
オプションは、入力レコード分離文字を設定します(16進数または8進数として、変換についてはこちらを参照してください)。ここ040
では、スペースである8進数に設定しています。これ-p
により、perl
各入力が「行」で印刷され、レコード区切り文字がスペースに設定されたため、行はスペースで定義されるようになり、すべてのフィールドが2回印刷されます。
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
標準入力から:
$ 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
)です。