Linux / Bash: как снять кавычки? - PullRequest
8 голосов
/ 09 августа 2011

Следующая команда

echo 'a b' 'c'

выводит

a b c

Но следующее

X="'a b' 'c'"
echo $X;

выйдет из строя

'a b' 'c'

Я ищуспособ снять кавычки с $ X, чтобы он выводил «abc», но без потери объединенного аргумента «ab».(= 2 аргумента вместо 3, не имеет значения для команды 'echo', но для других команд, таких как 'cp') *

Ответы [ 8 ]

8 голосов
/ 09 августа 2011

Попробуйте xargs:

$ echo $x
'a b' 'c'

$ echo $x | xargs ./echo
argc = 3
argv[0] = ./echo
argv[1] = a b
argv[2] = c
7 голосов
/ 09 августа 2011
eval echo $x

это передаст a b в качестве первого аргумента и c в качестве второго аргумента

Примечание: это фактически оценит аргументы, например:

$ x='$((3+5))'
$ eval echo $x
8

Если этоне то, что вы хотите, используйте @ vanza's xargs.

2 голосов
/ 09 августа 2011

Обычно, если вы пытаетесь сохранить несколько «слов» в одной переменной, рекомендуется не использовать встроенные кавычки, а использовать массив:

X=('a b' 'c')
printf "%s\n" "${X[@]}"

печать:

a b
c
0 голосов
/ 25 августа 2017

Пожалуйста, не используйте eval для чего-то подобного. set сохранит целостность параметров, а команды, отличные от echo, будут хорошо с ними работать. Просто помните, что вы потеряете ссылку (и) на любые текущие позиционные параметры.

set -- "a b" "c"
echo "$@"
#a b c
echo $1
#a b
echo $2
#c
0 голосов
/ 24 января 2014

Также возможно объединить xargs и sh -c 'cmd' _ arg1 arg2 ... для повторного разбора аргументов в массив позиционных параметров $@.

Назначение вывода переменной и перенаправление чего-либо, кроме состояния выхода $? последнего процесса, например, на stderr, позволяет сохранить код выхода последнего процесса в переменной и использовать его после xargs завершил исполнение.

X="'a b' 'c'"

ret="$(
export IFS=''
set -o pipefail
echo $X | xargs sh -c '
   for file in "$@"; do
      echo cp "$file" destdir 1>&2 || { echo $?; kill -HUP $PPID; exit $?; } 
      #(exit 3) || { echo $?; kill -HUP $PPID; exit $?; }
      #(exit 3) || { echo $?; kill -HUP $PPID; kill -HUP -- -$$; }
  done
  echo $?
' _
echo $? '|' ${PIPESTATUS[@]} 1>&2
)"
echo "$ret" | tail -1
0 голосов
/ 09 августа 2011

Вы уверены, что echo получает 2 параметра в echo $X? Для меня он получает 3. Давайте попробуем:

X="'a b' 'c'"
function f(){ echo $#; echo $1; echo $2; echo $3; }
f $X

отображает:

3
'a
b'
'c'

3 параметра: 'a, b' и 'c'. Я не думаю, что это то, что вы ожидаете.

Если вы хотите построить многопараметрическую переменную, установите IFS на символ, который вы не будете использовать (возможно, |), и используйте его как разделитель параметров в вашей переменной:

X="a b|c"
IFS="|"
function f(){ echo $#; echo $1; echo $2; }
f $X
0 голосов
/ 09 августа 2011
X="'a b' 'c'"
echo $X
eval "echo $X"

При использовании этого кода вы должны быть осторожны, если X может содержать специальные символы, такие как \"$ или обратные галочки.

0 голосов
/ 09 августа 2011

Это проблема, я бы порекомендовал обойти эту проблему и не объединять "ab" и "c" в первую очередь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...