Разделить строка с несколькими разделителями в bash

Предполагая, что подкаталоги расположены непосредственно в верхнем каталоге:

#!/bin/sh

topdir="$1"

for dir in "$topdir"/*/; do
    set -- "$dir"/*.ar

    if [ "$#" -eq 1 ] && [ ! -f "$1" ]; then
        # do things when no files were found
        # "$1" will be the pattern "$dir"/*.ar with * unexpanded
    elif [ "$#" -lt 3 ]; then
        # do things when less than 3 files were found
        # the filenames are in "$@"        
    elif [ "$#" -eq 3 ]; then
        # do things when 3 files were found
    elif [ "$#" -eq 4 ]; then
        # do things when 4 files were found
    else
        # do things when more than 4 files were found
    fi
done

Или, используяcase:

#!/bin/sh

topdir="$1"

for dir in "$topdir"/*/; do
    set -- "$dir"/*.ar

    if [ "$#" -eq 1 ] && [ ! -f "$1" ]; then
        # no files found
    fi

    case "$#" in
        [12])
            # less than 3 files found
            ;;
        3)
            # 3 files found
            ;;
        4)
            # 4 files found
            ;;
        *)
            # more than 4 files found
    esac
done

Ветви кода, которым требуется имя файла, используют "$@"для ссылки на все имена файлов в подкаталоге или "$1", "$2"и т. д. для ссылки на отдельные файлы. Имена файлов будут путями, включая каталог $topdirв начале.

0
17.03.2020, 18:25
3 ответа
sed -e 's/[^.]*.//' -e 's/;[^.]*./; /g'

Сначала удаляется самая короткая подстрока до .с самого начала, а затем можно полагаться на ;для обработки результирующей строки.

2
28.04.2021, 23:20

Понимая "in bash" буквально, вы могли бы сделать что-то подобное.

  • разбить строку на массив, разделенный точкой с запятой

  • удалить префикс поэлементно и сохранить результат в строке, разделенной первым символом IFS

  • глобально добавить обратно пробел после разделителей

ПРИМЕЧАНИЕ. :вы можете сохранить текущий IFS, чтобы потом восстановить его.

IFS=";"
read -a arr <<< "onetwothree.file.001.txt ; threefourfive.file.0.98.txt ; fivefoursix.file.14.txt"
printf -v str "${arr[*]#*.}"
printf "%s\n" "${str//;/; }"

джинвинг

file.001.txt ; file.0.98.txt ; file.14.txt
2
28.04.2021, 23:20

Или, с sed...

s="onetwothree.file.001.txt ; threefourfive.file.0.98.txt ; fivefoursix.file.14.txt"
sed -E "s/(^|; )[^\.]+\./\1/g" <<<$s

Прохождение

(^|; )[^\.]+\.

Найдите любой вложенный элемент -, который либо начинается в начале строки ^, либо |с;(точкой с запятой и пробелом )и за которым следует [^\.]+\., т. е. непрерывный ряд который не содержит литерала ., но который действительно заканчивается литералом.

Затем замените все это на \1, которое является группой захвата(^|; )

Выход

file.001.txt ; file.0.98.txt ; file.14.txt
2
28.04.2021, 23:20

Теги

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