Решение Python:
import re,sys;
for l in sys.stdin:
if 'ADD' in l:
data = [re.split(",",l.rstrip("\n"))[0].split()[-1]]+re.split(",",l.rstrip("\n"))[1:]
print " ".join(data)
data = []
Протестировано с пользовательским файлом на основе примера OP:
$ cat input.txt
cop1010 ADD atra522,Allison Track,CT,canada
some other stuff
testuser ADD test522,Allison TEST,CT,germany
$ python user_data.py < input.txt
atra522 Allison Track CT canada
test522 Allison TEST CT germany
Для совместимости с python 3 и хорошей печати данных мы могли бы сделать что-то вроде этого:
$ cat user_data.py
from __future__ import print_function
import re,sys;
for l in sys.stdin:
if 'ADD' in l:
data = [re.split(",",l.rstrip("\n"))[0].split()[-1]]+re.split(",",l.rstrip("\n"))[1:]
print("Username: " + data[0])
print("Real Name: " + data[1])
print("Some kind of two char string: "+ data[2])
print("Location: " + data[3])
print("- - -")
data = []
$ python user_data.py < input.txt
Username: atra522
Real Name: Allison Track
Some kind of two char string: CT
Location: canada
- - -
Username: test522
Real Name: Allison TEST
Some kind of two char string: CT
Location: germany
- - -
Наивный способ был бы следующим:
eval "dirin=$dirin"
Это оценивает расширение dirin = $ dirin
как шелл-кода.
С дирин
, содержащим ~ / foo
, он фактически вычисляет:
dirin=~/foo
Легко увидеть ограничения. С dirin
, содержащим foo bar
, это становится:
dirin=foo bar
Итак, он работает bar
с dirin = foo
в его среде (и у вас будут другие проблемы со всеми специальными символами оболочки).
Здесь вам нужно решить, какие расширения разрешены (тильда, подстановка команд, расширение параметров, подстановка процесса, арифметическое расширение, расширение имени файла ...), и либо выполнить эти замены вручную, либо использовать eval
но экранируют все символы, кроме тех, которые позволяют им, что было бы практически невозможно, кроме как путем реализации полного синтаксического анализатора оболочки, если вы не ограничите его, например, ~ foo
, $ VAR
, $ {VAR}
.
Здесь я бы использовал zsh
вместо bash
, у которого есть специальный оператор для этого:
vared -cp "input> " dirin
printf "%s\n" "${(e)dirin}"
vared
- это редактор переменных , аналогично bash
read -e
.
(e)
- это флаг расширения параметра, который выполняет раскрытие (параметр, команда, арифметика, но не тильда) в содержимом параметра.
Чтобы обратиться к раскрытию тильды, которое имеет место только в начале строки, мы должны сделать:
vared -cp "input> " dirin
if [[ $dirin =~ '^(~[[:alnum:]_.-]*(/|$))(.*)' ]]; then
eval "dirin=$match[1]\${(e)match[3]}"
else
dirin=${(e)dirin}
fi
POSIXly (так bash
ly), чтобы выполнить тильду и переменную (не параметр ), вы можете написать такую функцию, как:
expand_var() {
eval "_ev_var=\${$1}"
_ev_outvar=
_ev_v=${_ev_var%%/*}
case $_ev_v in
(?*[![:alnum:]._-]*) ;;
("~"*)
eval "_ev_outvar=$_ev_v"; _ev_var=${_ev_var#"$_ev_v"}
esac
while :; do
case $_ev_var in
(*'$'*)
_ev_outvar=$_ev_outvar${_ev_var%%"$"*}
_ev_var=${_ev_var#*"$"}
case $_ev_var in
('{'*'}'*)
_ev_v=${_ev_var%%\}*}
_ev_v=${_ev_v#"{"}
case $_ev_v in
"" | [![:alpha:]_]* | *[![:alnum:]_]*) _ev_outvar=$_ev_outvar\$ ;;
(*) eval "_ev_outvar=\$_ev_outvar\${$_ev_v}"; _ev_var=${_ev_var#*\}};;
esac;;
([[:alpha:]_]*)
_ev_v=${_ev_var%%[![:alnum:]_]*}
eval "_ev_outvar=\$_ev_outvar\$$_ev_v"
_ev_var=${_ev_var#"$_ev_v"};;
(*)
_ev_outvar=$_ev_outvar\$
esac;;
(*)
_ev_outvar=$_ev_outvar$_ev_var
break
esac
done
eval "$1=\$_ev_outvar"
}
Пример:
$ var='~mail/$USER'
$ expand_var var;
$ printf '%s\n' "$var"
/var/mail/stephane
В качестве приближения мы могли бы также добавить каждый символ, кроме ~ $ {} -_.
и alnums с обратной косой чертой перед переходом к eval
:
eval "dirin=$(
printf '%s\n' "$dirin" |
sed 's/[^[:alnum:]~${}_.-]/\\&/g')"
(здесь упрощено на том основании, что $ dirin
не может содержать символы новой строки, поскольку это происходит из читать
)
Это вызовет синтаксические ошибки, если ввести $ {foo # bar}
, например, но, по крайней мере, это не принесет большого вреда, как простой eval
. .
Изменить : рабочим решением для bash
и других оболочек POSIX было бы разделение тильды и других расширений, как в zsh
, и использование eval
с здесь-документом для других расширений , например:
expand_var() {
eval "_ev_var=\${$1}"
_ev_outvar=
_ev_v=${_ev_var%%/*}
case $_ev_v in
(?*[![:alnum:]._-]*) ;;
("~"*)
eval "_ev_outvar=$_ev_v"; _ev_var=${_ev_var#"$_ev_v"}
esac
eval "$1=\$_ev_outvar\$(cat << //unlikely//
$_ev_var
//unlikely//
)"
Это позволит расширять тильду, параметры, арифметические операции и команды, как в zsh
выше.
}