如何在bash中循环移动字符串?

时间:2010-04-05 12:23:06

标签: bash shell text-parsing

我有一个家庭作业,我需要从文件中获取输入并连续删除行中的第一个单词并将其附加到行的末尾,直到完成所有组合。

我真的不知道从哪里开始,并会感谢任何方向。

令我困惑的部分是假设在不使用数组的情况下执行。我不只是为了解决这个问题而找人解决问题,我只是想找点方向。

SAMPlE INPUT:

Pipes and Filters
Java Swing
Software Requirements Analysis

SAMPLE OUTPUT:

Analysis Software Requirements
Filters Pipes and
Java Swing
Pipes and Filters
Requirements Analysis Software
Software Requirements Analysis
Swing Java

7 个答案:

答案 0 :(得分:6)

一些应该有用的花絮:当你用一个字符串调用一个函数时,字符串被分成多个参数(positional parameters,名为$n,其中 n 是1)从变量$IFS中的字符开始的整数(默认为空格,制表符和换行符)

function first() {
    echo $1
}
first one two three
# outputs: "one"

$* and $@按顺序为您提供所有位置参数。

其次,特殊变量$#包含函数的参数个数。

第三,shift丢弃第一个位置参数,并将所有其他参数向上移动一个。

function tail() {
    shift
    echo $*
}

第四,您可以使用`...` or $(...)

捕获命令和函数的输出
rest=`tail $*`

第五,您可以使用pipe character|)将一个命令的输出发送到另一个命令的输入:

seq 5 | sort

答案 1 :(得分:3)

为了帮助您入门,请查看read内置版:

while read first_word rest_of_the_line; do
    ... your code here ...
done

您还需要一种方法将输入文件输入到该循环中。

答案 2 :(得分:3)

让我向您展示一个基于@outis answer的快速工作示例:

strings="string1 string2 string3"
next() { echo $1; }
rest() { shift; echo $*; }
for i in $strings; do
  echo $(next $strings)
  strings=$(rest $strings)
done

或者其他方式如果你对按顺序遍历感兴趣:

strings="string1 string2 string3"
next() { echo $1; }
rest() { shift; echo $*; }
totalWords=$(c() { echo $#; }; c $strings)
for i in `seq -w 1 $totalWords`; do
  echo $i: $(next $strings)
  strings=$(rest $strings)
done

答案 3 :(得分:0)

参数展开可让您分割变量的部分内容。

答案 4 :(得分:0)

这是简短的演示。翻阅单词,得到最后一个单词并放在字符串前面。直到最后一个字符串与原始字符串相同。

    #!/bin/bash    
    s="Software Requirements Analysis"
    org="$s"
    while true
    do
       last=${s##* } #Analysis
       front=${s% *} #Software Requirements
       s="$last $front"
       echo $s
       case "$s" in
         "$org") break;;
       esac
    done

你应该可以使用文件来完成剩下的工作。

答案 5 :(得分:0)

Bash允许您使用子字符串表示法处理位置参数。

$ foo() { for ((i=1; i<=$#; i++)) { printf '%s ' "${@:$i}" "${@:1:$((i-1))}"; echo; }; }
$ foo one two three
one two three
two three one
three one two

然后,处理多行输入就像一个while循环一样简单:

$ while read -a a; do foo "${a[@]}"; done < input.txt
Pipes and Filters
and Filters Pipes
Filters Pipes and
Java Swing
Swing Java
Software Requirements Analysis
Requirements Analysis Software
Analysis Software Requirements

或者,如果您喜欢冒险,甚至:

$ while read; do foo $REPLY; done < input.txt

对于您的示例输出应该如何获得顺序,我看不到任何解释,因此该解决方案忽略了问题的这一方面。

请注意,这不能处理所有排列/组合,仅处理您在问题中指定的排列/组合。

答案 6 :(得分:0)

这里是如何使字符串中的字符循环左移,以及如何使一行中的字符向左循环。

#!/bin/bash


# To left circular shift a string by chars
#
buf='12345'
bufsize=5

echo buf="$buf"
echo bufsize=$bufsize

for i in $(seq 10) c d e f; do
    buf=${buf:1:$bufsize}${buf:0:1}
    echo $buf
done

echo '--------------------------------------'
# to left circular shift a string by words
buf='one two three four "big bug"'
function lcs()
{
    s=$1
    shift
    echo $@ $s
}
for i in $(seq 10) c d e f; do
    buf=$(lcs $buf)
    echo $buf
done

输出

$ ./test
buf=12345
bufsize=5
23451
34512
45123
51234
12345
23451
34512
45123
51234
12345
23451
34512
45123
51234
--------------------------------------
two three four "big bug" one
three four "big bug" one two
four "big bug" one two three
"big bug" one two three four
bug" one two three four "big
one two three four "big bug"
two three four "big bug" one
three four "big bug" one two
four "big bug" one two three
"big bug" one two three four
bug" one two three four "big
one two three four "big bug"
two three four "big bug" one
three four "big bug" one two