Напишите функцию, которая проверяет, начинается ли строка с чего-то или содержит что-то

В вашем примере был изменен только каталог. Вы можете отключить atime, добавивnodiratime(только каталоги )илиnoatime(файлы и каталоги, включаяnodiratime)в параметры монтирования в /etc/fstab. Тогда должно измениться только ctime.

По умолчанию в ядре используется значение relatime, если оно не переопределено и отображается при выполнении команды mount.

крепление (8)

 relatime
              Update  inode  access  times relative to modify or change time.  Access time is only
              updated if the previous access time was earlier than the current  modify  or  change
              time.   (Similar  to  noatime,  but it doesn't break mutt or other applications that
              need to know if a file has been read since the last time it was modified.)

              Since Linux 2.6.30, the kernel defaults to the  behavior  provided  by  this  option
              (unless  noatime  was  specified),  and the strictatime option is required to obtain
              traditional semantics.  In addition, since Linux 2.6.30, the file's last access time
              is always updated if it is more than 1 day old.

Кстати. ваш chmod здесь не работает. Вы имели в виду chmod -R u=rwx,g=rwx,o=rwx test?

6
08.06.2019, 07:27
3 ответа

Пересмотрено на основании уточнения вопроса:Это менее элегантно (и гораздо менее гибко ). но более компактный, чем другие ответы,

check_func() {
        case "$1" in
            ( aa* | abc* | 3@3*  | *">"*)
                return 0
        esac
        return 1
}

Это возвращает true для aardvark, abcdef, 3@3com.comи 12>5. И, конечно, также aard>vark, abc<def>ghiи 3@3>3.

4
27.01.2020, 20:20

Вот что делает оператор case:передает второй параметр функции($2). Если он соответствует шаблону "$1"*, т. е. первому аргументу функции, за которым следует что-либо, выполните trueи завершите оператор case. trueничего не делает и возвращает статус 0. В противном случае, если он соответствует *, то есть чему угодно, выполнить falseи завершить оператор case. falseничего не делает и возвращает статус 1. Таким образом, оператор caseимеет статус 0, если второй параметр начинается с первого параметра, и 1 в противном случае. Поскольку это последний оператор (и единственный оператор )в функции, функция возвращает 0, если второй параметр начинается с первого параметра, и 1 в противном случае.

Условные операторы, такие как ifв оболочке, считают оператор истинным, если он возвращает 0, и ложным в противном случае. Следовательно, if beginswith "$var" "string"; then echo yes; else echo no; fiпечатает yes, если значение varначинается с string, и noв противном случае.

Существует несколько альтернативных способов написания этой функции. Например, автор мог бы использовать return 0или return 1вместо trueи false, так как они являются последним оператором в функции. Способ написания функции позволяет использовать ее тело напрямую, не оборачивая его в функцию, просто изменив ссылки на параметры функции($1и$2)на любые строки, с которыми вы хотите работать.

Чтобы разрешить несколько префиксов, выполните итерацию по ним в цикле. Как только вы найдете соответствующий префикс, вернитесь из функции с истинным статусом (0 ). Если ни один из префиксов не совпадает, вернуть ложный статус (условно 1 ).

# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2,...
begins_with () {
  string=$1
  shift
  for prefix in "$@"; do
    case "$string" in
      "$prefix"*) return 0;;
    esac
  done
  return 1
}

if begins_with "$var" 'aa' 'abc' '3@3'; then
  echo "The value starts with one of the permitted prefixes"
fi

Для проверки суффикса используйте шаблон *"$suffix"вместо "$prefix"*.Чтобы проверить подстроку, используйте *"$substring"*. Обратите внимание, что здесь необходимы двойные кавычки, иначе переменная будет интерпретироваться как шаблон. Например:

suffix='?'
case "$var" in
  *"$suffix") echo "The value of var ends with a question mark";; 
esac
case "$var" in
  *$suffix) echo "The value of var is not empty";; 
esac
4
27.01.2020, 20:20

Для удара:

Используя свойства регулярного выражения, вы можете написать startс ^и containничем.

Список регулярных выражений для проверки start сaaabcили 3@3и содержит>:

^aa ^abc ^3@3 >

Сделайте это должным образом цитируемым списком и попросите bash использовать регулярные выражения(=~):

check_func() {
               matched=1
               for test_regex in '^aa' '^abc' '^3@3' '>'; do
                   if [[ $var =~ $test_regex ]] ; then
                       matched=0
                       break 
                   fi
               done
               return "$matched"
              }

var='aaIsAMatch'
if check_func; then
    echo "A match was found"
fi

Функция жестко -закодировала список совпадений и имя переменной.

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

check_func() {
               local matched; matched=1
               for t in "${test_regex[@]}"; do
                   [[ $1 =~ $t ]] && { matched=0; break; } 
               done
               return "$matched"
              }


test_regex=('^aa' '^abc' '^3@3' '>')

if check_func 'aaIsAMatch'; then
    echo "A match was found"
fi

Функцию можно улучшить, чтобы использовать имя переменной (вместо значения )в качестве первого аргумента.

позикс

Поскольку в оболочках posix нет регулярных выражений, а единственным способом проверки является оператор case, мы должны использовать оператор case. К сожалению, для старых оболочек ([нет доступных расширенных глобусов][1] )мы должны выполнить все тесты в цикле. И шарики должны быть:

'aa*' 'abc*' '3@3*' '*>*'

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

check_func() { :
           matched=1
       value=$1; shift
           for t in "$@"; do
               case $value in $t) matched=0; #break;; esac
                  echo "matched $value with $t"
                  ;;
       esac
       done
           return "$matched"
         }


for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
        echo "========A match was found for \"$var\""
fi
done

Упрощенная версия функции, точно соответствующая вашему запросу:

check_func() { :
               matched=1
               value=$1; shift
                   for t in "$@"; do
                       case $value in $t) matched=0; break;; esac
                   done
               return "$matched"
             }
6
27.01.2020, 20:20

Теги

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