Проверить, содержит ли строка подстроку

Нет, поскольку вывод не дублируется. Чтобы продублировать файловые дескрипторы, вы также должны дважды вывести на них.

Хотя можно и с циклом, вот так:

while read l
do
   echo "$l" >&3
   echo "$l" >&4
done

С бинарными данными будут глючить (нули выбиты, crlf -s будут преобразованы в lf ).

Ваш пример сделал это:

  1. открыл fd 3 в файл
  2. клонировал fd 1 в вместо fd 3 (, т. е. он закрыл ваш предыдущий fd3, а затем сделал fd3 «альтернативным адресом» вашего предыдущего stdout ).

Перенаправление, по сути, является клоном, в терминологии Unix,это как жесткая ссылка. С суффиксом 3>&1к команде у вас будут fd 3 и fd 1, указывающие на один и тот же объект (, который теперьfile).

Если у вас есть некоторое сходство с C, я хотел бы проверить man 3 dup2, это именно то, что делает перенаправление fd.

43
14.06.2017, 00:51
4 ответа

Используйте оператор =~для сравнения регулярных выражений:

#!/bin/bash
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file =~ $testseq ]];
then
    echo "True"
else
    echo "False"
fi

Таким образом, он будет сравнивать, если $file содержит $testseq.

user@host:~$ ./string.sh
False

Если я изменю testseq="Const":

user@host:~$ ./string.sh
True

Но будьте осторожны с тем, что вы кормите $testseq. Если строка на нем каким-то образом представляет собой регулярное выражение (например, [0-9]), есть больше шансов вызвать «совпадение».

Ссылка:

34
27.01.2020, 19:35

Вам необходимо интерполировать переменную $testseqодним из следующих способов:

  • $file == *_"$testseq"_*(здесь $testseqрассматривается как фиксированная строка)

  • $file == *_${testseq}_*(здесь $testseqрассматривается как шаблон ).

Или _сразу после имени переменной будет считаться частью имени переменной (это допустимый символ в имени переменной ).

32
27.01.2020, 19:35
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"

case "$file" in
    *_"$testseq"_*) echo 'True'  ;;
    *)              echo 'False'
esac

Использование case... esac— один из самых простых способов выполнить сопоставление с образцом переносимым способом. В других языках он работает как оператор «switch» (bash, zshи ksh93, а также позволяет вам переходить -через различными несовместимыми способами ). Используемые шаблоны являются стандартными шаблонами подстановки имен файлов.

Проблема связана с тем, что _является допустимым символом в имени переменной. Таким образом, оболочка увидит *_$testseq_*как «*_, за которым следует значение переменной $testseq_и *». Переменная $testseq_не определена, поэтому она будет расширена до пустой строки, и вы получите *_*, что, очевидно, соответствует имеющемуся у вас значению $file. Вы можете ожидать получить True, если имя файла в $fileсодержит хотя бы одно подчеркивание.

Чтобы правильно разграничить имя переменной, используйте "..."вокруг расширения:*_"$testseq"_*.Это будет использовать значение переменной в виде строки. Если вы хотите использовать значение переменной как шаблон , используйте вместо этого *_${testseq}_*.

Еще одним быстрым решением является включение символов подчеркивания в значение$testseq:

testseq="_gen_"

, а затем просто используйте *"$testseq"*в качестве шаблона (для сравнения строк ).

23
27.01.2020, 19:35

Для портативного способа проверить, содержит ли строка подстроку, используйте:

file="JetConst_reco_allconst_4j2t.png";       testseq="gen"

[ "${file##*$testseq*}" ] || echo True Substring is present

Или "${file##*"$testseq"*}", чтобы избежать интерпретации символов подстановки в testseq.

4
27.01.2020, 19:35

Теги

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