Bash排列与单词列表

问题描述 投票:1回答:3

我有这样一句话:

The quick brown $UNKNOWN1 jumps over the $UNKNOWN2 dog

我有一个这样的世界列表:

me
black
lazy
swan
dog
word
sky
fox
nothing
you

我如何在bash中列出列表以具有所有排列,例如:

The quick brown you jumps over the nothing dog

The quick brown fox jumps over the lazy dog

等等,所有的排列。我尝试了一些for循环,但卡住了因为我认为我需要循环内部循环(嵌套循环)。就像是:

for i in `cat wordlist.txt`;
  do echo "The quick brown $i jumps over the $UNKNOWN2 dog";
done

编辑:

我觉得这就是:

#!/bin/bash

for i in `cat wordlist.txt`
  do
    for a in `cat wordlist.txt`
      do
        echo "The quick brown $i jumps over the $a dog"
    done
done
bash permutation
3个回答
1
投票

我想我需要在循环内部循环。

你是对的:

for i in $(cat wordlist.txt)
do
  for j in $(cat wordlist.txt)
  do
    echo "The quick brown $i jumps over the $j dog"
  done
done

你可以选择在$i = $j时避免使用它:

for i in $(cat wordlist.txt); do
  for j in $(cat wordlist.txt); do
    if [ "$i" != "$j" ]; then
      echo "The quick brown $i jumps over the $j dog"
    fi
  done
done

4
投票

只是为了好玩,GNU Parallel也很擅长排列:

parallel echo The quick brown {1} jumps over the {2} dog :::: wordlist.txt :::: wordlist.txt

或者,相同,但省略两个单词相同的行:

parallel 'bash -c "[ {1} != {2} ] && echo The quick brown {1} jumps over the {2} dog"' :::: wordlist.txt wordlist.txt

1
投票

还有一个没有循环的hacky替代方案:

printf "The quick brown %s jumps over the %s dog.\n" $(join -j 2 words words)

在这种情况下,join创建单词列表的笛卡尔积。结果是一个单词列表。每个单词都作为参数传递给printfprintf打印句子,将%s替换为列表中的下一个单词。打印一次句子后,它仍然有未读的单词并继续,直到所有单词都被打印出来。

优点:

  • 更短的计划
  • 比循环更快

缺点(与for i in $(cat wordlist)完全相同)

  • 由于max. number of arguments,可能会在长长的单词列表中失败。
  • 如果单词列表包含*?,这些可能会被bash扩展。
  • 单词列表中的单词必须是真实单词,不允许使用空格。
© www.soinside.com 2019 - 2024. All rights reserved.