LinuxForum.Fans
Тема

[SOLVED]вопрос по sed внутри скрипта

Автор: merlin 11 сообщений 4043 просмотров
#273137

Здравствуйте. Я пытаюсь научиться писать bash скрипты. Есть такой скрипт:

text

ya@debian:/mnt/maindisk/temp$ cat my_first_script | more
#!/bin/sh
unixize () {
    echo "$1" | sed -e 's%\\%/%g' | sed -e 's%^\([A-Za-z]\):%/\1%'
}
test_var=`unixize "c:\docs\test"`
echo $test_var
ya@debian:/mnt/maindisk/temp$ 

Задумывалось, что выполнение подобного скрипта вернет

text

/c/docs/test

Однако я получаю

text

ya@debian:/mnt/maindisk/temp$ ./my_first_script
/c/docs est
ya@debian:/mnt/maindisk/temp$

Подскажите пожалуйста, где ошибка.

#273139

cat my_first_script | more

drBatty это увидит - загнобит)

а по теме:

у меня возвращает именно то, что вы предполагали...

Есть вариант, что у Вас прописан alias и echo "$1" исполняется ,как echo -e "$1".
В этом случае /t воспринимается как горизонтальный таб и не заменяется.

#273140
"NoXi0uZ" написал:
drBatty это увидит - загнобит)

А что не так, можно поинтересоваться?

"NoXi0uZ" написал:
у меня возвращает именно то, что вы предполагали...

Хм, может в дебиан squeeze sed слишком старый, поэтому и не работает как следует.

#273141
"merlin" написал:
А что не так, можно поинтересоваться?

ну чем плохо

text
 less my_first_script

или

text
 more my_first_script
"merlin" написал:
sed слишком старый

это очень вряд ли... Надо смотреть, кто из них воспринимает \t за табуляцию (echo или sed)

#273143
"NoXi0uZ" написал:
Есть вариант, что у Вас прописан alias и echo "$1" исполняется ,как echo -e "$1".

Да нет вроде, ничего не прописано

text
ya@debian:/mnt/maindisk/temp$ alias
alias ls='ls --color=auto'
ya@debian:/mnt/maindisk/temp$ 
#273145
text
$ cat test.sh
#!/bin/sh

unixize() { echo "$1" | sed -e 's%\\%/%g' | sed -e 's%^\([A-Za-z]\):%/\1%' }

test_var=`unixize "c:\docs\test"` echo $test_var $ ./test.sh /c/docs/test

ЧЯДНТ???
У меня - unixize(), а у вас - unixize (). Не в этом ли дело?
UPD: нет, оба варианта работают.
Значит, смотрите переменные окружения.

#273146

Перезагрузился в gentoo, все работает как и должно. Так что видимо это какие то проблемы стабильного дебиана.

#273147

Дело могло быть в переменной окружения $IFS:

text
$ cat test.sh 
#!/bin/sh

IFS="\t" unixize () { echo "$1" | sed -e 's%\\%/%g' | sed -e 's%^\([A-Za-z]\):%/\1%' }

test_var=`unixize "c:\docs\test"` echo $test_var ./test.sh /c/docs/ es

#273174
"yars" написал:
Дело могло быть в переменной окружения $IFS:

Вроде бы не похоже,

text

ya@debian:/mnt/maindisk/temp$ more my_first_script
#!/bin/sh
IFS=","
unixize () {
    echo "$1" | sed -e 's%\\%/%g' | sed -e 's%^\([A-Za-z]\):
%/\1%'
}
test_var=`unixize "c:\docs\test"`
echo "$test_var"
ya@debian:/mnt/maindisk/temp$ sh my_first_script
/c/docs est
#273360

Доброго времени!

Есть вариант, что у Вас прописан alias и echo "$1" исполняется ,как echo -e "$1".
В этом случае /t воспринимается как горизонтальный таб и не заменяется.

Правильная мысль, «неправильная причина»

Я пытаюсь научиться писать bash скрипты

Тогда пишите на bash'е, а не том shell'е, что используется по умолчанию в данной (версии) ОС.
В начале скрипта Вы указываете интерпретатор, http://ru.wikipedia.org/wiki/Интерпретатор
К примеру, для perl'а это может быть так
#!/usr/bin/perl
а для python'а
#!/usr/bin/python
Вот этой строкой

#!/bin/sh

замените на #!/bin/bash и на всех системах, где установлен bash он будет выполняться одинакова (конечно, нужно помнить, что bash может иметь различные версии и конфигурационные параметры).

http://ru.wikipedia.org/wiki/Командная_оболочка_UNIX

Вместо того, чтобы придерживаться синтаксиса конкретной реализации командной оболочки UNIX-like, Вы могли бы придерживаться стандартов POSIX, http://ru.wikipedia.org/wiki/POSIX
По умолчанию, в debian, в качестве /bin/sh
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 date /bin/sh -> dash

Dash это POSIX совместимая оболочка, http://ru.wikipedia.org/wiki/Debian_Almquist_shell
Bash в свою очередь, по умолчанию, не POSIX совместимая.
Согласно стандартам POSIX, echo всегда интерпретирует escape sequence, http://ru.wikipedia.org/wiki/Управляющая_последовательность

text
$ echo $0
bash
$ set -o | grep posix
posix              off
$ test="c:\docs\test"
$ echo $test
c:\docs\test

$ echo $0 dash $ test="c:\docs\test" $ echo $test c:\docs est

Не стоит также забывать, что обычно на GNU//Linux системах, доступны сразу две реализации echo, встроенная и coreutils

text
$ echo $0
dash
$ test="c:\docs\test"
$ echo $test
c:\docs    est
$ /bin/echo $test
c:\docs\test

http://man.cat-v.org/unix-6th/1/echo
http://man.cat-v.org/unix_8th/1/echo
http://www.in-ulm.de/~mascheck/bourne/v7/
http://www.gnu.org/software/bash/manual/bashref.html#index-echo
http://www.gnu.org/software/coreutils/manual/coreutils.html#echo-invocation
http://pubs.opengroup.org/onlinepubs/009695399/utilities/echo.html
http://pubs.opengroup.org/onlinepubs/009695399/utilities/printf.html
http://www.freebsd.org/cgi/man.cgi?query=echo&apropos=0&sektion=0&manpath=FreeBSD+9.0-RELEASE&arch=default&format=html
http://www.openbsd.org/cgi-bin/man.cgi?query=echo&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html
http://netbsd.gw.com/cgi-bin/man-cgi?echo++NetBSD-current

Стоит обратить внимание на configure скрипты и посмотреть, как они устроенны.

text
$ wget [url]http://ftp.gnu.org/gnu/coreutils/coreutils-8.19.tar.xz[/url]
$ tar xf coreutils-8.19.tar.xz
$ cd coreutils-8.19
$ cat configure | less
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
        expr "X$arg" : "X\\(.*\\)$as_nl";
        arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '
    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi
  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'
fi

Вместо echo используется переменная as_echo
$ grep -m 1 ac_cs_config configure
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"

Закругляясь, методы устранения Вашей «несовместимости».
- Ранее названный, указать #!/bin/bash
- Использовать echo из coreutils

text
$ echo $0
dash
$ test="c:\docs\test"
$ echo $test
c:\docs    est
$ /bin/echo $test
c:\docs\test

- Использовать printf

text
$ echo $0
dash
$ test="c:\docs\test"
$ echo $test
c:\docs    est
$ printf "%s\n" $test
c:\docs\test

cat my_first_script | more

Мне зачастую удобней конструкция с конвейером.

впредь прошу польззоваться тегом [сode] для оформления сообщений... Fat-Zer

#273429

K.8H.wxtOfaVg, спасибо за исчерпывающий и развернутый ответ.

Войдите или зарегистрируйтесь, чтобы ответить.