Зачем вы делаете while True
, а затем выходите из этого цикла, в то время как вы также можете просто поместить свои требования в оператор while, поскольку все, что вы хотите, останавливается, когда у вас есть возраст?
age = None
while age is None:
input_value = input("Please enter your age: ")
try:
# try and convert the string input to a number
age = int(input_value)
except ValueError:
# tell the user off
print("{input} is not a number, please enter a number only".format(input=input_value))
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
Это приведет к следующему:
Please enter your age: *potato*
potato is not a number, please enter a number only
Please enter your age: *5*
You are not able to vote in the United States.
это будет работать, поскольку возраст никогда не будет иметь значения, которое не имеет смысла, а код следует логике вашего «бизнес-процесса»
Если вы действительно хотите просто использовать sed -i
«простой» способ, следующие работы работают как на GNU, так и на BSD / Mac sed
:
sed -i.bak 's/foo/bar/' filename
Обратите внимание на нехватку места и точка.
Доказательство:
# GNU sed
% sed --version | head -1
GNU sed version 4.2.1
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
# BSD sed
% sed --version 2>&1 | head -1
sed: illegal option -- -
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
Очевидно, вы могли бы просто удалить файлы .bak
.
Нет способа заставить его работать.
Один из способов - использовать временный файл, например:
TMP_FILE=`mktemp /tmp/config.XXXXXXXXXX`
sed -e "s/abc/def/" some/file > $TMP_FILE
mv $TMP_FILE some/file
Это работает как на
Ответ Стива Пауэлла совершенно верный, консультирование на странице MAN для sed на OSX и Linux (Ubuntu 12.04) подчеркивает совместимость в режиме «на месте» в двух операционных системах.
JFYI, не должно быть пробелов между -i и любыми кавычками (которые обозначают пустое расширение файла), используя версию sed для Linux, таким образом
#Linux
sed -i""
и
#OSX (notice the space after the '-i' argument)
sed -i ""
Я обошел это в скрипт с помощью команды alias'd и вывода OS-имени «uname» в bash «if». Попытка хранить OS-зависимые командные строки в переменных была удалена и пропущена при интерпретации кавычек. Использование «shopt -s expand_aliases» необходимо для расширения / использования псевдонимов, определенных в вашем скрипте. Использование магазина {g3] здесь .
В Linux и OS X работает следующее:
sed -i' ' <expr> <file>
, например. для файла f
, содержащего aaabbaaba
sed -i' ' 's/b/c/g' f
, выдается aaaccaaca
как на Linux, так и на Mac. Обратите внимание, что имеется строка с кавычками , содержащая пробел , при этом нет пробела между -i
и строкой. Одинарные или двойные кавычки работают.
В Linux я использую bash
версию 4.3.11 под Ubuntu 14.04.4 и на Mac версии 3.2.57 под OS X 10.11.4 El Capitan (Darwin 15.4 0,0).
Вы можете использовать губку. Sponge - старая программа unix, найденная в пакете moreutils (как в ubuntu, так и, вероятно, в debian, и в homebrew в mac).
Он будет буферизовать все содержимое из канала, дождитесь закрытия канала (возможно, это значит, что входной файл уже закрыт), а затем перезапишите:
Из man page :
Сводка
sed '...' file | grep '...' | файл губки
Вот еще одна версия, которая работает на Linux и macOS без использования eval
и без необходимости удалять файлы резервных копий. Он использует массивы Bash для хранения параметров sed
, которые чище, чем использование eval
:
# Default case for Linux sed, just use "-i"
sedi=(-i)
case "$(uname)" in
# For macOS, use two parameters
Darwin*) sedi=(-i "")
esac
# Expand the parameters in the actual call to "sed"
sed "${sedi[@]}" -e 's/foo/bar/' target.file
Это не создает файл резервной копии, ни файл с добавленными кавычками.
Если вам нужно сделать sed
на месте в сценарии bash
, и вы НЕ хотите, чтобы на месте было результат с .bkp-файлами, и у вас есть способ обнаружить os (скажем, используя ostype.sh ), - тогда следующий хак с встроенной bash
оболочкой eval
должен работать:
OSTYPE="$(bash ostype.sh)"
cat > myfile.txt <<"EOF"
1111
2222
EOF
if [ "$OSTYPE" == "osx" ]; then
ISED='-i ""'
else # $OSTYPE == linux64
ISED='-i""'
fi
eval sed $ISED 's/2222/bbbb/g' myfile.txt
ls
# GNU and OSX: still only myfile.txt there
cat myfile.txt
# GNU and OSX: both print:
# 1111
# bbbb
# NOTE:
# if you just use `sed $ISED 's/2222/bbbb/g' myfile.txt` without `eval`,
# then you will get a backup file with quotations in the file name,
# - that is, `myfile.txt""`
Это работает с GNU sed, но не на OS X:
sed -i -e 's/foo/bar/' target.file
sed -i'' -e 's/foo/bar/' target.file
Это работает на OS X, но не с GNU sed:
sed -i '' -e 's/foo/bar/' target.file
В OS X вы
sed -i -e
, так как расширение файла резервной копии будет установлено на -e
sed -i'' -e
по тем же причинам -It требуется пространство между -i
и ''
. Когда в OSX я всегда устанавливаю версию GNU sed через Homebrew, чтобы избежать проблем с скриптами, потому что большинство скриптов были написаны для версий GNU sed.
brew install gnu-sed --with-default-names
Затем ваше BSD sed будет заменено на GNU sed.
В качестве альтернативы вы можете установить без имен по умолчанию, но затем:
Ответ: Нет.
Первоначально принятый ответ фактически не выполняет то, что запрашивается (как отмечено в комментариях). (Я нашел этот ответ, когда искал причину, по которой file-e
появлялся «случайно» в моих каталогах.)
По-видимому, нет способа заставить sed -i
работать последовательно как на MacOS, так и на Linuces.
Моя рекомендация, для того, что она стоит, заключается не в обновлении с помощью sed
(который имеет сложные режимы сбоя), а для создания новых файлов и последующего их переименования. Другими словами: избегайте -i
.
Параметр -i
не является частью POSIX Sed . Более переносимым способом было бы использовать Vim в режиме Ex:
ex -sc '%s/alfa/bravo/|x' file
%
выбрать все строки s
заменить x
сохранить и закрыть Я столкнулся с этой проблемой. Единственным быстрым решением было заменить sed в mac на версию gnu:
brew install gnu-sed
sed
) – slezica 24 June 2015 в 21:10sed
не принимает аргумент positionalcommand
при вызове с-i
- it must i> be с другим флагом-e
. Таким образом, команда становится:sed -i.bak -e 's/foo/bar/' filename
– ELLIOTTCABLE 16 May 2017 в 19:22sed -i.bak 's/foo/bar/' file && rm file.bak
– joeytwiddle 13 March 2018 в 05:02