Как сделать круговой сдвиг строк в bash? - PullRequest
6 голосов
/ 05 апреля 2010

У меня есть домашнее задание, в котором мне нужно взять данные из файла, непрерывно удалять первое слово в строке и добавлять его в конец строки, пока не будут выполнены все комбинации.

Я действительно не знаю, с чего начать, и был бы благодарен за любое направление.

То, что меня смутило, состоит в том, что это должно быть выполнено без использования массивов. Я не просто ловлю кого-то, чтобы решить проблему для меня, я просто ищу направление.

ОБРАЗЕЦ ВХОДА:

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

Ответы [ 6 ]

6 голосов
/ 05 апреля 2010

Несколько лакомых кусочков, которые должны помочь: при вызове функции со строкой строка разбивается на несколько аргументов ( позиционные параметры , с именем $<i>n</i>, где n целые числа, начинающиеся с 1) символов в переменной $IFS (по умолчанию пробелы, табуляции и новые строки)

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

$* и $@ дают вам все позиционные параметры по порядку.

Во-вторых, специальная переменная $# содержит количество аргументов функции.

В-третьих, shift отбрасывает первый позиционный параметр и сдвигает все остальные на один.

function tail() {
    shift
    echo $*
}

В-четвертых, вы можете захватить вывод команд и функций, используя `...` или $(...)

rest=`tail $*`

В-пятых, вы можете отправить вывод одной команды на вход другой, используя символ (|):

seq 5 | sort
3 голосов
/ 08 мая 2015

Позвольте мне показать вам быстрый рабочий пример на основе @ 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 голосов
/ 05 апреля 2010

Для начала ознакомьтесь со встроенным read:

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

Вам также нужен способ подачи входного файла в этот цикл.

0 голосов
/ 25 декабря 2018

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

Я не вижу никаких объяснений относительно того, как ваш пример выходных данных должен поступить в таком порядке, поэтому это решение игнорирует этот аспект вашего вопроса.

Обратите внимание, что это не обрабатывает все перестановки / комбинации, а только те, которые вы указали в своем вопросе.

0 голосов
/ 05 апреля 2010

это короткая демонстрация. Пролистайте слова, получите последнее слово и поставьте перед строкой. пока последняя строка не станет такой же, как оригинал.

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

Вы должны быть в состоянии сделать все остальное, используя файл.

0 голосов
/ 05 апреля 2010

Расширение параметра позволит вам вырезать части переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...