Split using sed

Упрощенный ваш сценарий должен выглядеть так:

#! bin/bash

input="${1}"    reverse=""

for   (( i=0; i<${#input}; i++ ))
do    reverse="${input:${i}:1}$reverse"
done
echo   "$reverse"

Предположим, вы поместили приведенный выше код в файл с именем script.sh и разрешите его выполнение: chmod u + x script.sh . Затем эта команда будет работать:

$ ./script.sh 0123456789
9876543210

Значение $ {# input} - это длина ввода (количество символов).
Цикл идет посимвольно от начала до конца.
Для выбора каждого символа сценарий использует инструмент bash под названием Substring Expansion.
Цитата из man bash (вы также можете получить к нему доступ, набрав man bash ):

$ {параметр: смещение: длина}
Расширение подстроки. Расширяется до символов максимальной длины параметра, начиная с символа, указанного в смещении.

Это означает, что каждый символ в позиции i выбирается по очереди для воссоздания строки в переменной reverse .

Но для этого вам не нужны никакие циклы или причудливое кодирование. Эта простая строка будет делать то же самое:

$ echo "0123456789" | rev
9876543210
1
08.05.2013, 09:40
2 ответа

Некоторые пояснения к комментарию / ответу @manatwork:

  • grep версия: grep '^ [^ |] \ + ||| \ (. \ + \? ||| \) \ 1 '

    • ^ : соответствует началу строки
    • [^ |] : соответствует любому исключенному символу |
    • \ + : сопоставить один или несколько раз с предыдущим шаблоном
    • ||| : ​​сопоставить ваш разделитель
    • \ ( и \) : сохранить значение, указанное в скобках в \ 1
    • . : сопоставить любой символ
    • \ + \? : один или несколько раз, но не жадный
    • ||| : сопоставить ваш разделитель еще раз
    • \ 1 : сопоставить предыдущий текст между скобками

    Идея здесь состоит в том, чтобы пропустить начало строки до первого разделителя, затем сохранить найденное значение до конца второго разделителя, а затем сопоставить только строку, имеющую точно такое же значение, как \ 1 после второго оператора (имеется в виду третье поле)

  • sed версия: sed -n '/ ^ [^ |] \ + ||| \ (. \ + \ ? ||| \) \ 1 / p '

    То же значение, что и grep , с дополнительными / в начале и в конце строки, чтобы указать шаблон, плюс дополнительная команда символ p в конце для печати совпадающих строк.

  • awk версия: awk -F '\\ | \\ | \\ |' '$ 2 == $ 3'

    • -F '\\ | \\ | \\ |' : укажите разделитель полей: ||| в данном случае экранирован
    • '$ 2 = = $ 3 ': фильтровать ввод только тогда, когда второе и третье поля равны
3
29.04.2021, 00:49

Я предпочитаю решение awk, но если вы хотите использовать только Bash, вот мой ответ:

foo() 
{ 
    local filename="$1";
    [[ $filename ]] || return 1

    while read -r line; do
        l="${line#*|||}"; a2="${l%%|||*}"
        l="${l#*|||}"; a3="${l%%|||*}"
        [[ $a2 = $a3 ]] && echo "$line"
    done < "$filename"
}

Использование: foo filename.txt

Образец вывода:

rany$ cat > filename.txt
a|||b|||c|||d|||
a|||b|||c|||d|||
a|||E|||E|||d|||
a|||B|||B|||d|||

rany$ foo filename.txt
a|||E|||E|||d|||
a|||B|||B|||d|||
0
29.04.2021, 00:49

Теги

Похожие вопросы