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

发布于 2024-08-27 12:30:01 字数 502 浏览 7 评论 0原文

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

我真的不知道从哪里开始,非常感谢任何类型的指导。

让我感到困惑的部分是,这应该是在不使用数组的情况下执行的。我不仅仅是在寻找某人来为我解决问题,我只是在寻找方向。

样本输入:

Pipes and Filters
Java Swing
Software Requirements Analysis

样本输出:

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

I have a homework assignment where I need to take input from a file and continuously remove the first word in a line and append it to the end of the line until all combinations have been done.

I really don't know where to begin and would be thankful for any sort of direction.

The part that has me confused is that this is suppose to be performed without the use of arrays. I'm not just fishing for someone to solve the problem for me, I'm just looking for some direction.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

做个少女永远怀春 2024-09-03 12:30:01

一些应该有所帮助的花絮:当您使用字符串调用函数时,该字符串被分成多个参数(位置参数,名为$n,其中n是整数从 1) 开始,变量 < code>$IFS (默认为空格、制表符和换行符)

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

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

二、特殊变量 $ # 保存函数的参数数量。

第三,shift< /code>丢弃第一个位置参数并将所有其他位置参数上移一个。

function tail() {
    shift
    echo $*
}

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

rest=`tail $*`

第五,您可以使用 管道符 (|):

seq 5 | sort

A few tidbits that should help: when you call a function with a string, the string is split into multiple arguments (the positional parameters, named $n, where n are integers starting at 1) on the characters in the variable $IFS (which defaults to spaces, tabs and newlines)

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

$* and $@ give you all the positional parameters, in order.

Second, the special variable $# holds the number of arguments to a function.

Third, shift discards the first positional parameter and moves up all the others by one.

function tail() {
    shift
    echo $*
}

Fourth, you can capture the output of commands and functions using `...` or $(...)

rest=`tail $*`

Fifth, you can send the output of one command to the input of another using the pipe character (|):

seq 5 | sort
蒲公英的约定 2024-09-03 12:30:01

首先,请查看内置的 read

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

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

To get you started, check out the read builtin:

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

You also need a way to feed your input file into that loop.

猫弦 2024-09-03 12:30:01

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

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

Let me allow to show you a quick working example based on @outis answer:

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

Or other way-round if you're interested in traversing by sequence:

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
冷夜 2024-09-03 12:30:01

这是简短的演示。遍历单词,得到最后一个单词并将其放在字符串前面。直到最终的字符串与原来的字符串相同。

    #!/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

您应该能够使用文件完成其余的工作。

this is short demo. Go through the words, get the last word and put in front of the string. until the final string is the same as the original.

    #!/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

you should be able to do the rest using a file.

挽心 2024-09-03 12:30:01

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

我没有看到任何关于示例输出应该如何进入的解释该顺序,因此该解决方案忽略了您问题的这方面。

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

Bash lets you address positional parameters using substring notation.

$ 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

Then, handling multiple lines of input is as simple as a while loop:

$ 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

Or if you're feeling adventurous, even:

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

I don't see any explanation as to how your sample output is supposed to get in that order, so this solution ignores that aspect of your question.

Note that this doesn't handle all permutations/combinations, only the ones you specified in your question.

隐诗 2024-09-03 12:30:01

以下是如何循环左移字符串中的字符以及如何循环左移一行上的单词。

#!/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

Here is how you can circular left shift the chars in a string and how to circular left shift words on a line.

#!/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

output

$ ./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
眼藏柔 2024-09-03 12:30:01

参数扩展可以让您删除变量的一部分。

Parameter expansion will let you carve off parts of a variable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文