svn switch --relocate
ожидает находить тот же репозиторий в новом URL, не другой.
Вы использовали svnsync
создать новый репозиторий? В этом случае можно использовать svnadmin setuuid
использовать тот же uuid в качестве старого репозитория. Согласно svnsync документации в книге svn, это должно позволить Вам снова использовать существующие рабочие копии.
IFS=$' \t\n'
. Иначе Вы могли ввести коды элемента управления литерал при помощи [space] CTRL+V [tab] CTRL+V [enter]
. Если Вы планируете сделать это, однако, лучше использовать другую переменную для временного хранения старого IFS
значение, и затем восстанавливает его впоследствии (или временно переопределяет его для одной команды при помощи var=foo command
синтаксис).$line
, как нет никаких разделителей полей для выполнения разделения слова для. Примите во внимание однако, что, так как много оболочек используют cstrings для хранения строк, первая инстанция NUL может все еще вызвать появление его преждевременно завершаемый.$line
. Например, если будет несколько последовательных разделителей полей, то они будут превращены в единственный экземпляр первого элемента. Это часто распознается как потеря окружающего пробела.Q1: Да. “Полевое разделение” и “разделение слова” являются двумя условиями для того же понятия.
Q2: да. Если IFS
сброшен (т.е. после unset IFS
), это эквивалентно IFS
быть установленным на $' \t\n'
(пространство, вкладка и новая строка). Если IFS
установлен на пустое значение (это - то, что “пустой указатель” означает здесь) (т.е. после IFS=
или IFS=''
или IFS=""
), никакое полевое разделение не выполняется вообще (и $*
, который обычно использует первый символ $IFS
, использует пробел).
Q3: Если Вы хотите иметь значение по умолчанию IFS
поведение, можно использовать unset IFS
. Если Вы хотите установить IFS
явно к этому значению по умолчанию, можно поместить пространство буквенных символов, вкладку, новую строку в одинарных кавычках. В ksh93, ударе или zsh, можно использовать IFS=$' \t\n'
. Портативно, если Вы не хотите иметь литеральный символ табуляции в своем исходном файле, можно использовать
IFS=" $(echo t | tr t \\t)
"
Q4: с IFS
набор к пустому значению, read -r line
наборы line
к целой строке кроме ее новой строки завершения. С IFS=" "
, пробелы вначале и в конце строки обрезаются. Со значением по умолчанию IFS
, вкладки и пробелы обрезаются.
$@
, существуют некоторые изменения между оболочками в контекстах несписка как IFS=; var=$@
). Нужно отметить, что, когда IFS пуста, никакое разделение слова не выполняется, но $var все еще не расширяется ни до какого аргумента вместо пустого аргумента, когда $var пуст, и globbing все еще применяется, таким образом, все еще необходимо заключить переменные в кавычки (даже при отключении globbing)
– Stéphane Chazelas
09.02.2013, 00:19
unset IFS
действительно очищает IFS, даже если IFS, как после этого предполагают, является "\t\n":
$ echo "'$IFS'"
'
'
$ IFS=""
$ echo "'$IFS'"
''
$ unset IFS
$ echo "'$IFS'"
''
$ IFS=$' \t\n'
$ echo "'$IFS'"
'
'
$
Протестированный на версиях 4.2.45 и 3.2.25 удара с тем же поведением.
Разделение полей - это то же самое, что разделение слов?
Да, оба указывают на одну и ту же идею.
Параметр
IFS = ''
такой же, как null, то же самое, что и пустая строка?
Да, все три означают одно и то же: разделение полей / слов выполняться не будет. {{ 1}} Кроме того, это влияет на поля печати (как в случае echo "$ *"
), все поля будут объединены вместе без пробелов.
В спецификации POSIX я прочитал следующее :
Если IFS не установлен, оболочка должна вести себя так, как если бы значение IFS было <пробел>
<новая строка > .
Что в точности эквивалентно:
При неустановленном
IFS
оболочка должна вести себя так, как если бы IFS был установлен по умолчанию.
Это означает, что «Разделение полей» будет точно таким же со значением IFS по умолчанию или не задано.
Это НЕ означает, что IFS будет работать одинаково во всех условиях.
Более конкретно, выполнение OldIFS = $ IFS
установит переменную OldIFS
до null , а не значение по умолчанию. И попытка вернуть IFS, например, IFS = OldIFS
установит IFS в ноль, а не оставит его неустановленным, как это было раньше. Осторожно !!.
Как мне восстановить значение IFS по умолчанию. Скажем, я хочу восстановить значение IFS по умолчанию.Как мне это сделать? (более конкретно, как мне сослаться на
и ?)
Для zsh, ksh и bash (AFAIK) IFS может быть установлен на значение по умолчанию:
IFS=$' \t\n' # works with zsh, ksh, bash.
Готово, больше ничего читать не нужно.
Но если вам нужно переустановить IFS для sh, это может стать сложным.
Давайте посмотрим от самого простого к законченному без недостатков (кроме сложности).
Мы могли бы просто отключить IFS
(прочтите Q3, часть a, выше).
В качестве обходного пути замена значения табуляции и новой строки упрощает установку значения IFS, а затем работает аналогичным образом.
Установите IFS на <пробел> <новая строка>
sh -c 'IFS=$(echo " \n\t"); printf "%s" "$IFS"|xxd' # Works.
Если есть дочерние сценарии, которым необходимо правильно установить IFS, вы всегда можете вручную написать:
IFS=' '
Где последовательность, введенная вручную, была: IFS =
' пробел tab новая строка ', последовательность, которая была правильно введена выше (если вам нужно подтвердить, отредактируйте этот ответ). Но копирование / вставка из вашего браузера не работает, потому что браузер сжимает / скрывает пробелы. Это затрудняет совместное использование кода, как написано выше.
Для написания кода, который можно безопасно скопировать, обычно требуются однозначные печатные escape-последовательности.
Нам нужен код, который «производит» ожидаемое значение. Но, даже если концептуально верен, этот код НЕ будет устанавливать завершающий \ n
:
sh -c 'IFS=$(echo " \t\n"); printf "%s" "$IFS"|xxd' # wrong.
Это происходит потому, что в большинстве командных интерпретаторов все завершающие символы новой строки $ (...)
или `...`
подстановки команд удаляются при расширении.
Нам нужно использовать трюк для sh:
sh -c 'IFS="$(printf " \t\nx")"; IFS="${IFS%x}"; printf "$IFS"|xxd' # Correct.
Альтернативным способом может быть установка IFS как значение среды из bash (например), а затем вызов sh (его версии, которые принимают IFS должен быть установлен через среду), например:
env IFS=$' \t\n' sh -c 'printf "%s" "$IFS"|xxd'
Короче говоря, sh делает сброс IFS по умолчанию довольно странным приключением.
И, наконец, как этот код:
в то время как IFS = read -r line do echo $ line done < / path_to_text_file
ведет себя, если мы изменим первую строку на
при чтении -r line # Использовать значение IFS по умолчанию
или:
при IFS = '' read -r line
Во-первых: я не знаю, есть ли echo $ line
(с var NOT в кавычках) на porpouse или нет. {{1} } Он вводит второй уровень «разделения полей», которого у чтения нет.
Так что я отвечу на оба. :)
С помощью этого кода (чтобы вы могли подтвердить). Вам понадобится полезный xxd :
#!/bin/ksh
# Correctly set IFS as described above.
defIFS="$(printf " \t\nx")"; defIFS="${defIFS%x}";
IFS="$defIFS"
printf "IFS value: "
printf "%s" "$IFS"| xxd -p
a=' bar baz quz '; l="${#a}"
printf "var value : %${l}s-" "$a" ; printf "%s\n" "$a" | xxd -p
printf "%s\n" "$a" | while IFS='x' read -r line; do
printf "IFS --x-- : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
printf 'Values quoted :\n' "" # With values quoted:
printf "%s\n" "$a" | while IFS='' read -r line; do
printf "IFS null quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
printf "%s\n" "$a" | while IFS="$defIFS" read -r line; do
printf "IFS default quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
unset IFS; printf "%s\n" "$a" | while read -r line; do
printf "IFS unset quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
IFS="$defIFS" # set IFS back to default.
printf "%s\n" "$a" | while IFS=' ' read -r line; do
printf "IFS space quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
printf '%s\n' "Values unquoted :" # Now with values unquoted:
printf "%s\n" "$a" | while IFS='x' read -r line; do
printf "IFS --x-- unquoted : "
printf "%s, " $line; printf "%s," $line |xxd -p; done
printf "%s\n" "$a" | while IFS='' read -r line; do
printf "IFS null unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
printf "%s\n" "$a" | while IFS="$defIFS" read -r line; do
printf "IFS defau unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
unset IFS; printf "%s\n" "$a" | while read -r line; do
printf "IFS unset unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
IFS="$defIFS" # set IFS back to default.
printf "%s\n" "$a" | while IFS=' ' read -r line; do
printf "IFS space unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
Я получаю:
$ ./stackexchange-Understanding-IFS.sh
IFS value: 20090a
var value : bar baz quz -20202062617220202062617a20202071757a2020200a
IFS --x-- : bar baz quz -20202062617220202062617a20202071757a202020
Values quoted :
IFS null quoted : bar baz quz -20202062617220202062617a20202071757a202020
IFS default quoted : bar baz quz-62617220202062617a20202071757a
IFS unset quoted : bar baz quz-62617220202062617a20202071757a
IFS space quoted : bar baz quz-62617220202062617a20202071757a
Values unquoted :
IFS --x-- unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS null unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS defau unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS unset unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS space unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
Первое значение - это просто правильное значение IFS =
' пробел tab newline '
Следующая строка - это все шестнадцатеричные значения, которые имеет var $ a
, и новая строка «0a» в конце, поскольку она будет передаваться каждой команде чтения. .
Следующая строка, для которой IFS имеет значение NULL, не выполняет никакого «разделения полей», но новая строка удаляется (как и ожидалось).
Следующие три строки, поскольку IFS содержит пробел, удаляют начальные пробелы и устанавливают в строке var значение остатка баланса.
Последние четыре строки показывают, что будет делать переменная без кавычек.Значения будут разделены на (несколько) пробелов и будут напечатаны как: bar, baz, qux,
IFS
и сбросIFS
очень отличаются. Ответ на Q4 является частично неправильным: внутренние разделители не затронуты здесь, только ведя и запаздывающие. – Gilles 'SO- stop being evil' 14.12.2011, 14:06IFS
, все они имеют в видуIFS=
. – Stéphane Gimenez 14.12.2011, 15:00IFS=' ' ; foo=( bar baz qux ) ; echo "${#foo[@]}"
. (Er, что? Там должно быть несколько разделителей пространства, ТАКИМ ОБРАЗОМ, механизм продолжает разделять их). – Chris Down 14.12.2011, 18:05read
; последняя переменная захватывает все, что это оставляют за исключением последнего разделителя и оставляет внутренние разделители внутри. – Gilles 'SO- stop being evil' 15.12.2011, 17:25