Bash脚本重复一行中的每个单词?


13

我有一个像这样的字符串: dog cat bird whale

我想得到 dog dog cat cat bird bird whale whale

所有的单词都在同一行。任何想法?

Answers:


28

添加到解决方案系列中:-)。

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

4
我喜欢shell方法的简单性。
Henk Langeveld 2014年

好吧,我真的很喜欢这个解决方案的简单性
Cristian 2014年

比我想到的前两种方法要好。
2014年

21

您可以使用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包含打开自动拆分模式时读入的每一行的字段。参见perlrun进行-a切换。此数组是特定于程序包的,如果在下运行,则必须在包主目录中声明该数组或为其指定完整的包名strict 'vars'


4
简称:sed -r 's/\S+/& &/g'
赛勒斯

2
那不是Bash脚本。调用某些命令(即使是从Bash shell中)也不构成Bash脚本。
Peter Mortensen 2014年

4
@PeterMortensen您在技术上是正确的(最好的一种正确的选择),但是实际上,每个安装了bash的系统也将具有标准的UNIX工具,包括sed和awk。Shell脚本编写的重点(很重要的一点)是将命令指向正确的位置。
evilsoup 2014年

3
@PeterMortensen这是不正确的。bash脚本可以调用外部命令。bash脚本应以shebang行开头,但这不是严格必要的。该问题未指定bash脚本不应调用外部命令(通常称为“纯bash脚本”)。
吉尔斯(Gillles)“所以-别再邪恶了”

2
不错的perl技巧。您可以使用以下方法使其更短-aperl -M5.10.0 -ane 'say join " ", map{$_, $_} @F;'
terdon

4

没有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"

我的第一张选票。只是好奇,为什么?脚本有问题吗?还是更简短的版本?
user19087 2014年

for(i=1;i<=NF;++i) printf "%s %s ",$i,$i;恕我直言,这不是我的不赞成,但更简短,也更具可读性。
rici 2014年

对此很难争论,因此我在不改变方法的情况下简化并缩短了答案(现在利用了将索引四舍五入为整数的优势)。希望现在更加清晰。
user19087 2014年

1
那不是Bash脚本。调用某些命令(即使是从Bash shell中)也不构成Bash脚本。
Peter Mortensen 2014年

但是,将其放在脚本中是微不足道的。
凯文(Kevin)


1

如果您将字符串包含在变量中,请说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

    说明:需要括号,以便readand 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.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,即一个空格。该-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;这只是简写)。


0

现在寻求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

0

有点过分,但有一个haskell答案:

$ ghc -e "getLine >>= putStrLn . unwords . (concatMap $ replicate 2) . words" <<<"dog cat bird whale"
dog dog cat cat bird bird whale whale

0

另一种方法,也仅使用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)内置的shell 。
Daniel Andersson 2014年

@DanielAndersson:当然,这就是为什么我写了“ 只使用bash内置函数”的原因,并牢记了一个不错的答案(已经+1)。
mpy

好的,您可以将我的评论归类为语言混乱:-)。
丹尼尔·安德森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.