Есть ли в оболочке что-то похожее на JavaScript "split()"?

Обычно необходимо создать некоторый файл учетных данных и использовать его при монтировании долей cifs/samba. Вот пример с помощью fstab

# insecure and common usage
//share/dir /mnt/myshare cifs username=user,password=pass

# more secure usage
Create a credentials file in /etc/ that has 0600 permissions for root.
Call it fileshare

//share/dir /mt/myshare cifs credentials=/etc/fileshare

cat /etc/fileshare
username=yourusername
password=youpass

Можно затем смонтировать его вручную, если Вам нравится путем выполнения этого.

smbmount //share/dir /mnt/myshare -o credentials=/etc/fileshare
19
08.09.2015, 16:09
2 ответа

Оболочки Bourne / POSIX имеют оператор split + glob, который вызывается каждый раз, когда вы оставляете раскрытие параметра ( $ var , $ - ...), подстановка команд ( $ (...) ) или арифметическое раскрытие ( $ ((...)) ) без кавычек в контексте списка.

На самом деле, вы вызвали его по ошибке, когда вы сделали для имени в $ {array [@]} вместо для имени в "$ {array [@]}" . (На самом деле, вы должны знать, что такой ошибочный вызов этого оператора является источником многих ошибок и уязвимостей безопасности ).

Этот оператор сконфигурирован со специальным параметром $ IFS (чтобы указать, какие символы разделять (но имейте в виду, что пробел, табуляция и новая строка там обрабатываются особым образом)) и -f Параметр для отключения ( set -f ) или включения ( set + f ) части glob .

Также обратите внимание, что хотя S в $ IFS изначально был (в оболочке Борна, откуда $ IFS ) для S eparator, в оболочках POSIX символы в $ IFS лучше рассматривать как разделители или терминаторы (см. пример ниже).

Итак, чтобы разделить на _ :

string='var1_var2_var3'
IFS=_ # delimit on _
set -f # disable the glob part
array=($string) # invoke the split+glob operator

for i in "${array[@]}"; do # loop over the array elements.

Чтобы увидеть различие между разделителем и разделителем , попробуйте:

string='var1_var2_'

Это разделит его на Только var1 и var2 (без лишних пустых элементов).

Итак, чтобы сделать его похожим на split () в JavaScript, вам понадобится дополнительный шаг:

string='var1_var2_var3'
IFS=_ # delimit on _
set -f # disable the glob part
temp=${string}_ # add an extra delimiter
array=($temp) # invoke the split+glob operator

(обратите внимание, что он разделит пустую $ string на 1 (не 0 ) элемент, как в JavaScript split () ).

Чтобы увидеть вкладку специальных обработок, пробел и новую строку, сравните:

IFS=' '; string=' var1  var2  '

(где вы получаете var1 и var2 ) с

IFS='_'; string='_var1__var2__'

, где вы получаете: '' , var1 , '' , var2 , '' .

Обратите внимание, что оболочка zsh не вызывает этот оператор split + glob неявно, как это, кроме случаев эмуляции sh или ksh . Здесь вы должны вызвать его явно. $ = string для разделенной части, $ ~ string для части glob ( $ = ~ string для обеих), а также имеет оператор разделения, где вы можете указать разделитель:

array=(${(s:_:)string})

или сохранить пустые элементы:

array=("${(@s:_:)string}")

Обратите внимание, что там s предназначены для разделения , а не разделения (также с $ IFS , известное несоответствие POSIX zsh ). Он отличается от JavaScript split () тем, что пустая строка разбивается на 0 (а не на 1) элемент.

Заметная разница с разделением $ IFS состоит в том, что $ {(s: abc:) string} разбивается на строку abc , а с IFS = abc , который разделится на a , b или c .

В zsh и ksh93 особую обработку пробелов, табуляции или новой строки можно удалить, удвоив их в $ IFS .

Как историческое примечание, оболочка Bourne (предок или современные оболочки POSIX) всегда удаляла пустые элементы. Он также имел ряд ошибок, связанных с разделением и расширением $ @ с нестандартными значениями $ IFS . Например, IFS = _; set -f; набор --$ @ не будет эквивалентно IFS = _; set -f; набор - 1 $ 2 $ 3 ... .

Разделение на регулярные выражения

Теперь для чего-то более близкого к JavaScript split () , который может разбивать на регулярные выражения, вам нужно будет полагаться на внешние утилиты.

В инструментарии POSIX awk имеет оператор split , который может разбивать на расширенные регулярные выражения (это более или менее подмножество Perl-подобные регулярные выражения, поддерживаемые JavaScript).

split() {
  awk -v q="'" '
    function quote(s) {
      gsub(q, q "\\" q q, s)
      return q s q
    }
    BEGIN {
      n = split(ARGV[1], a, ARGV[2])
      for (i = 1; i <= n; i++) printf " %s", quote(a[i])
      exit
    }' "$@"
}
string=a__b_+c
eval "array=($(split "$string" '[_+]+'))"

Оболочка zsh имеет встроенную поддержку Perl-совместимых регулярных выражений (в модуле zsh / pcre ), но использование ее для разделения строки, хотя и возможно, относительно громоздко.

24
27.01.2020, 19:45

Да, используйте IFS и установите ее на _. Затем используйте read -a для хранения в массиве (-r отключает расширение обратного слеша). Обратите внимание, что это специфично для bash; ksh и zsh имеют схожие свойства с немного другим синтаксисом, а plain sh вообще не имеет переменных массива.

$ r="var1_var2_var3"
$ IFS='_' read -r -a array <<< "$r"
$ for name in "${array[@]}"; do echo "+ $name"; done
+ var1
+ var2
+ var3

Из man bash:

read

-a aname

Слова присваиваются последовательным индексам переменной массива Имя, начинающееся с 0. Имя не задается до того, как новые значения будут назначено. Другие аргументы имени игнорируются.

IFS

Внутренний разделитель полей, который используется для разделения слов после расширение и разделение строк на слова с прочитанной строкой командование. Значение по умолчанию ``''.

Обратите внимание, что чтение останавливается на первой новой строке. Чтобы избежать этого, передайте -d '' на read, но в этом случае в конце появится дополнительная новая строка из-за оператора <<. Вы можете удалить его вручную:

IFS='_' read -r -d '' -a array <<< "$r"
array[$((${#array[@]}-1))]=${array[$((${#array[@]}-1))]%?}
7
27.01.2020, 19:45

Теги

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