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

或者作为 shell 函数,例如可以在脚本中重复使用:

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包含打开自动分割模式时读入的每一行的字段。请参阅 perlrun 了解-a开关。此数组是特定于包的,如果在 下运行时不在包 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",你可以这样做:

  • 纯 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在同一个子 shell 中,从而可以共享变量。如果没有括号,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.2)等等。这样,第一个文件的每个字段都会打印两次。但是,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即空格。这-pperl打印每个输入“行”,并且由于我们已将记录分隔符设置为空格,因此行现在由空格定义,因此每个字段都会打印两次。

  • 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 的简写)。

相关内容