行内のすべての単語を繰り返す Bash スクリプトはありますか?

行内のすべての単語を繰り返す Bash スクリプトはありますか?

次のような文字列があります:dog cat bird whale

そして私はdog dog cat cat bird bird whale whale

すべての単語が同じ行にあります。何か分かりますか?

答え1

ソリューション ファミリーに追加します :-) 。

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

答え2

次のように使用できます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'

答え3

答えがなければ、これは何になるでしょうか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"

答え4

たとえば、文字列を変数に格納している場合は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.2)を印刷するように指示しています。このように、1番目のファイルの各フィールドは2回印刷されます。ただし、joinは、結合するように設計されています。共通フィールドに行を入力します。そのため、空白行 ( <(echo)) も渡して無視します。 は-j結合フィールドを設定し、存在しないフィールド (5 番目) に設定すると、join行全体が印刷されます。

    空白や入力順序を気にしないのであれば、次のようにすればよい。

    $ paste <(echo $foo) <(echo $foo)
    dog cat bird wale   dog cat bird wale
    
  • パール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'
    
  • パール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;は print の省略形です)。

関連情報