Необходимо извлечь подстроку из строки пути файла, включая разделитель

При выполнении сценария оболочки строка ввода похожа на следующую:

test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class

Как я могу извлечь: test1/test2/Test.jar [т.е. подстрока до первого появления разделителя .jar, включительно], в сценарии оболочки

Как это сделать? Я бы не хотел использовать cut, а затем добавить «.jar» в конец.

Спасибо

6
задан 26 July 2017 в 07:53

15 ответов

Вы можете использовать sed, как показано ниже:

sed 's/\(\.jar\).*/\1/' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class" 

Или через команду awk:

awk -F'\\.jar' '{print $1".jar"}' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Выход:

test1/test2/Test.jar
6
ответ дан 22 May 2018 в 20:10

Вы можете использовать sed, как показано ниже:

sed 's/\(\.jar\).*/\1/' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Или через команду awk:

awk -F'\\.jar' '{print $1".jar"}' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Выход:

test1/test2/Test.jar
6
ответ дан 18 July 2018 в 09:39

Вы можете использовать sed, как показано ниже:

sed 's/\(\.jar\).*/\1/' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Или через команду awk:

awk -F'\\.jar' '{print $1".jar"}' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Выход:

test1/test2/Test.jar
6
ответ дан 24 July 2018 в 19:23

Кроме sed, вы также можете использовать grep для этого с помощью регулярного выражения PCRE ^.*?\.jar:

grep -oP '^.*?\.jar' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Это выводит только совпадение (-o), использует Кроме sed (-P) и соответствует тексту, который:

начинается с начала строки (^) и содержит любой символ (.), любое число раз, но лениво согласовано (*?), за которым следует буквальный символ . (\.) и jar (jar)

Используя ленивый квантификатор [ f14] вместо обычного жадного квантификатора * вызывает grep, чтобы соответствовать наименьшему количеству символов.

начинается в начале строки (^) и Флаг -P требуется, потому что на диалектах regex grep поддерживается Ubuntu, PCRE - это тот, который поддерживает лень. (Этот диалект очень похож на диалект регулярного выражения в Perl.)
8
ответ дан 22 May 2018 в 20:10

Поскольку вы упоминаете сценарий оболочки, я представляю простое, чисто основанное на оболочке решение:

s='test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class'
echo "${s%%.jar*}.jar"

Расширение параметра %% удаляет самый длинный суффикс, который соответствует последующему шаблону glob .jar* (в противоположность на %, который соответствует кратчайшему суффиксу).

6
ответ дан 22 May 2018 в 20:10
  • 1
    %% является стандартным. Разделы Expansion IEEE 1003.1-2008 , IEEE 1003.1 и SUSv2 все покрывают его как «Удалить Самый большой шаблон суффикса. & Quot; Хотя не все оболочки в стиле Бурна соответствуют стандартам, я считаю, что %% настолько же портативен, как и большинство других функций оболочки, которые, как мы обычно говорим, являются переносимыми. – Eliah Kagan 31 July 2017 в 05:56
  • 2
    @EliahKagan: Спасибо! Я соответствующим образом удалил эти части вопроса. – David Foerster 31 July 2017 в 10:14

В python:

python3 -c "print('blub/blab/Test.jar/blieb'.split('.jar')[0]+'.jar')"

> blub/blab/Test.jar

или:

python3 -c "s='blub/blab/Test.jar/blieb';print(s[:s.find('.jar')+4])"

> blub/blab/Test.jar
3
ответ дан 22 May 2018 в 20:10

Поскольку этот вопрос отмечен bash, вот скрипт bash с расширением параметра C-стиля и ${variable:beginning:offset} для извлечения отдельных символов

#!/usr/bin/env bash

substring=""
for ((i=0;i<=${#1};i++))
do
    substring="$substring""${1:$i:1}"
    if [[ "$substring" == *.jar ]]
    then
        echo "$substring"
        substring=""
    fi
done

Это работает так:

$ ./parse_string.sh test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class                                                                              
test1/test2/Test.jar
/Test2.jar

Если мы хотим извлечь только первое вхождение, добавьте break в строку после substring="" внутри if оператора

3
ответ дан 22 May 2018 в 20:10
  • 1
    Зачем использовать C-loop? Почему не только ${str//.jar*/.jar}? – terdon♦ 26 July 2017 в 13:42
  • 2
    @DavidFoerster pls публикует это как ответ - IMHO, это, безусловно, предпочтительнее всех решений sed / awk / grep / perl, предлагаемых до сих пор – steeldriver 26 July 2017 в 15:25
  • 3
    @terdon, потому что итерация над символами строки - это первая идея, по которой мой разум тяготел по какой-то причине; нет конкретной причины. – Sergiy Kolodyazhnyy 26 July 2017 в 15:40
  • 4
    @DavidFoerster Я согласен с steeldriver. Возможно, вы захотите опубликовать это как ответ. – Sergiy Kolodyazhnyy 26 July 2017 в 15:41
  • 5
    @DavidFoerster спасибо - ответьте upvoted! – steeldriver 26 July 2017 в 19:45

Поскольку вы упоминаете сценарий оболочки, я представляю простое, чисто основанное на оболочке решение:

s='test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class' echo "${s%%.jar*}.jar"

Расширение параметра %% удаляет самый длинный суффикс, который соответствует последующему шаблону glob .jar* (в противоположность на %, который соответствует кратчайшему суффиксу).

6
ответ дан 18 July 2018 в 09:39

Кроме sed, вы также можете использовать grep для этого с помощью регулярного выражения PCRE ^.*?\.jar:

grep -oP '^.*?\.jar' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Это выводит только совпадение (-o), использует Кроме sed (-P) и соответствует тексту, который:

начинается с начала строки (^) и содержит любой символ (.), любое число раз, но лениво согласовано (*?), за которым следует буквальный символ . (\.) и jar (jar)

Используя ленивый квантификатор *? вместо обычного жадного квантификатора * вызывает grep, чтобы соответствовать наименьшему количеству символов.

начинается в начале строки (^) и Флаг -P требуется, потому что на диалектах regex grep поддерживается Ubuntu, PCRE - это тот, который поддерживает лень. (Этот диалект очень похож на диалект регулярного выражения в Perl.)
8
ответ дан 18 July 2018 в 09:39

В python:

python3 -c "print('blub/blab/Test.jar/blieb'.split('.jar')[0]+'.jar')" > blub/blab/Test.jar

или:

python3 -c "s='blub/blab/Test.jar/blieb';print(s[:s.find('.jar')+4])" > blub/blab/Test.jar
3
ответ дан 18 July 2018 в 09:39

Поскольку этот вопрос отмечен bash, вот скрипт bash с расширением параметра C-стиля и ${variable:beginning:offset} для извлечения отдельных символов

#!/usr/bin/env bash substring="" for ((i=0;i<=${#1};i++)) do substring="$substring""${1:$i:1}" if [[ "$substring" == *.jar ]] then echo "$substring" substring="" fi done

Это работает так:

$ ./parse_string.sh test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class test1/test2/Test.jar /Test2.jar

Если мы хотим извлечь только первое вхождение, добавьте break в строку после substring="" внутри if оператора

3
ответ дан 18 July 2018 в 09:39

Поскольку вы упоминаете сценарий оболочки, я представляю простое, чисто основанное на оболочке решение:

s='test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class' echo "${s%%.jar*}.jar"

Расширение параметра %% удаляет самый длинный суффикс, который соответствует последующему шаблону glob .jar* (в противоположность на %, который соответствует кратчайшему суффиксу).

6
ответ дан 24 July 2018 в 19:23
  • 1
    %% является стандартным. Разделы Expansion IEEE 1003.1-2008 , IEEE 1003.1 и SUSv2 все покрывают его как «Удалить Самый большой шаблон суффикса. & Quot; Хотя не все оболочки в стиле Бурна соответствуют стандартам, я считаю, что %% настолько же портативен, как и большинство других функций оболочки, которые, как мы обычно говорим, являются переносимыми. – Eliah Kagan 31 July 2017 в 05:56
  • 2
    @EliahKagan: Спасибо! Я соответствующим образом удалил эти части вопроса. – David Foerster 31 July 2017 в 10:14

Кроме sed, вы также можете использовать grep для этого с помощью регулярного выражения PCRE ^.*?\.jar:

grep -oP '^.*?\.jar' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"

Это выводит только совпадение (-o), использует Кроме sed (-P) и соответствует тексту, который:

начинается с начала строки (^) и содержит любой символ (.), любое число раз, но лениво согласовано (*?), за которым следует буквальный символ . (\.) и jar (jar)

Используя ленивый квантификатор *? вместо обычного жадного квантификатора * вызывает grep, чтобы соответствовать наименьшему количеству символов.

начинается в начале строки (^) и Флаг -P требуется, потому что на диалектах regex grep поддерживается Ubuntu, PCRE - это тот, который поддерживает лень. (Этот диалект очень похож на диалект регулярного выражения в Perl.)
8
ответ дан 24 July 2018 в 19:23

В python:

python3 -c "print('blub/blab/Test.jar/blieb'.split('.jar')[0]+'.jar')" > blub/blab/Test.jar

или:

python3 -c "s='blub/blab/Test.jar/blieb';print(s[:s.find('.jar')+4])" > blub/blab/Test.jar
3
ответ дан 24 July 2018 в 19:23

Поскольку этот вопрос отмечен bash, вот скрипт bash с расширением параметра C-стиля и ${variable:beginning:offset} для извлечения отдельных символов

#!/usr/bin/env bash substring="" for ((i=0;i<=${#1};i++)) do substring="$substring""${1:$i:1}" if [[ "$substring" == *.jar ]] then echo "$substring" substring="" fi done

Это работает так:

$ ./parse_string.sh test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class test1/test2/Test.jar /Test2.jar

Если мы хотим извлечь только первое вхождение, добавьте break в строку после substring="" внутри if оператора

3
ответ дан 24 July 2018 в 19:23
  • 1
    Зачем использовать C-loop? Почему не только ${str//.jar*/.jar}? – terdon♦ 26 July 2017 в 13:42
  • 2
    @DavidFoerster pls публикует это как ответ - IMHO, это, безусловно, предпочтительнее всех решений sed / awk / grep / perl, предлагаемых до сих пор – steeldriver 26 July 2017 в 15:25
  • 3
    @terdon, потому что итерация над символами строки - это первая идея, по которой мой разум тяготел по какой-то причине; нет конкретной причины. – Sergiy Kolodyazhnyy 26 July 2017 в 15:40
  • 4
    @DavidFoerster Я согласен с steeldriver. Возможно, вы захотите опубликовать это как ответ. – Sergiy Kolodyazhnyy 26 July 2017 в 15:41
  • 5
    @DavidFoerster спасибо - ответьте upvoted! – steeldriver 26 July 2017 в 19:45

Другие вопросы по тегам:

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