У меня есть сценарий оболочки с этим кодом:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
Но условный код всегда выполняется, потому что hg st
всегда печатает хотя бы один символ новой строки.
- Есть ли простой способ убрать пробелы из
$var
(какtrim()
в PHP )?
или
- Есть ли стандартный способ решения этой проблемы?
Я мог бы использовать sed или AWK , но я хотел бы думать, что есть более элегантное решение этой проблемы.
$ var=$(echo)
$ [ -n $var ]; echo $? #undesired test return
0
$ [[ -n $var ]]; echo $?
1
echo " This is a string of char " | xargs
. Однако , если вы имеете апостроф в тексте вы можете сделать следующее:echo " This i's a string of char " | xargs -0
. Обратите внимание, что я упоминаю последний из xargs (4.6.0)test=`echo`; if [ -n "$test" ]; then echo "Not empty"; fi
, однако это будетtest=`echo "a"`; if [ -n "$test" ]; then echo "Not empty"; fi
- поэтому в конце должно быть больше, чем просто перевод строки.echo $A | sed -r 's/( )+//g'
;Ответы:
Давайте определим переменную, содержащую начальные, конечные и промежуточные пробелы:
Как удалить все пробелы (обозначено
[:space:]
вtr
):Как удалить только первые пробелы:
Как удалить только конечные пробелы:
Как убрать как начальные, так и конечные пробелы - объедините
sed
:С другой стороны , если ваш Баш поддерживает его, вы можете заменить
echo -e "${FOO}" | sed ...
сsed ... <<<${FOO}
, например , так (для конечных пробелов):источник
tr
иsed
команде с[[:space:]]
. Обратите внимание, что этотsed
подход будет работать только на однострочном вводе. Подходы, которые работают с многострочным вводом, а также используют встроенные функции bash, см. В ответах @bashfu и @GuruM. Обобщенная, встроенная версия решения @Nicholas Sushkin будет выглядеть так:trimmed=$([[ " test test test " =~ [[:space:]]*([^[:space:]]|[^[:space:]].*[^[:space:]])[[:space:]]* ]]; echo -n "${BASH_REMATCH[1]}")
alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'"
к вашему~/.profile
позволяет вам использоватьecho $SOMEVAR | trim
иcat somefile | trim
.sed
решение , которое использует только одно выражение , а не два:sed -r 's/^\s*(\S+(\s+\S+)*)\s*$/\1/'
. Он обрезает начальные и конечные пробелы и фиксирует любые разделенные пробелами последовательности непробельных символов в середине. Наслаждайтесь!|
чтобы сохранить его как одно, а не несколько выражений.Простой ответ:
Xargs сделает обрезку для вас. Это одна команда / программа, без параметров, которая возвращает обрезанную строку, просто!
Примечание: это не удаляет все внутренние пробелы, поэтому
"foo bar"
остается неизменным; это НЕ становится"foobar"
. Тем не менее, несколько пробелов будут сжаты в единичные пробелы, поэтому"foo bar"
станет"foo bar"
. Кроме того, он не удаляет символы конца строки.источник
xargs echo
передать это просто, чтобы быть многословным о том, что я делаю, но xargs сам по себе будет использовать echo по умолчанию.sed 's/ *$//'
в качестве альтернативы. Вы можете увидетьxargs
новую строку следующим образом:echo -n "hey thiss " | xargs | hexdump
вы заметите,0a73
чтоa
это новая строка. Если вы сделаете то же самое сsed
:echo -n "hey thiss " | sed 's/ *$//' | hexdump
вы увидите0073
, нет новой строки.a<space><space>b
вa<space>b
. 2. Еще больше: оно превратитсяa"b"c'd'e
вabcde
. 3. Еще больше: он не включитсяa"b
и т. Д.Существует решение, которое использует только встроенные модули Bash, называемые подстановочными знаками :
Вот то же самое, заключенное в функцию:
Вы передаете строку для обрезки в кавычки. например:
Приятной особенностью этого решения является то, что оно будет работать с любой POSIX-совместимой оболочкой.
Ссылка
источник
s=" 1 2 3 "; echo \""${s%1 2 3 }"\"
урезать все с конца, возвращая ведущий" "
. Подбирая1 2 3
с[![:space:]]*
указывает, что «найти первый непробельный символ, а затем забить его и все после». Использование%%
вместо%
делает операцию отделки с конца жадной. Это вложено в не жадную обрезку с самого начала, так что, по сути, вы обрезаете" "
с самого начала. Затем поменяйте местами%, # и * для конечных пробелов. Бам!/bin/sh
(только с/usr/xpg4/bin/sh
, но это не то, что будет использоваться с обычными sh-скриптами).${var%%[![:space:]]*}
говорит «удалить изvar
самой длинной подстроки, которая начинается с непробельного символа». Это означает, что у вас остались только первые пробелы, которые вы впоследствии удалите${var#..
. Следующая строка (трейлинг) противоположна.awk
,sed
,tr
,xargs
) просто обрезки пробельного из одной строки в корне безумен - особенно , когда большинство оболочек ( в том числе Баша) уже обеспечивает встроенную строку munging объектов вне коробки.В Bash есть функция, называемая расширением параметров , которая, помимо прочего, позволяет заменять строки на основе так называемых шаблонов (шаблоны напоминают регулярные выражения, но есть фундаментальные различия и ограничения). [Оригинальная строка flussence: у Bash есть регулярные выражения, но они хорошо спрятаны:]
Ниже показано, как удалить все пустое пространство (даже изнутри) из значения переменной.
источник
${var/ /}
удаляет первый пробел${var// /}
удаляет все пробелы Нет способа обрезать только начальные и конечные пробелы только с помощью этой конструкции.Чтобы удалить все пробелы в начале и конце строки (включая символы конца строки):
Это также удалит дубликаты пробелов:
Производит: «в этой строке много пробелов»
источник
echo -n
вообще?echo " my string " | xargs
имеет такой же выход.Удалите один ведущий и один завершающий пробел
Например:
Вывод:
Убрать все ведущие и конечные пробелы
Например:
Вывод:
источник
'hello world ', 'foo bar', 'both sides '
Из раздела Bash Guide по глобализации
Использовать extglob в расширении параметра
Вот та же функциональность, заключенная в функцию (ПРИМЕЧАНИЕ: необходимо заключить в кавычки входную строку, переданную функции):
Применение:
Если мы изменим функцию для выполнения в подоболочке, нам не нужно беспокоиться о проверке текущей опции оболочки для extglob, мы можем просто установить ее, не затрагивая текущую оболочку. Это значительно упрощает функцию. Я также обновляю позиционные параметры «на месте», поэтому мне даже не нужна локальная переменная
так:
источник
extglob
, используяshopt -p
: просто напишитеlocal restore="$(shopt -p extglob)" ; shopt -s extglob
в начале вашей функции иeval "$restore"
в конце (за исключением того, что eval - это зло ...).[[:space:]]
можно заменить пробелом:${var##+( )}
и${var%%+( )}
работать, и их легче читать.Вы можете обрезать просто с помощью
echo
:источник
foo
содержит подстановочный знак? например,foo=" I * have a wild card"
... сюрприз! Более того, это объединяет несколько смежных пространств в одно.Я всегда делал это с помощью sed
Если есть более элегантное решение, я надеюсь, что кто-нибудь разместит его.
источник
sed
?sed -e 's/\s*$//'
. Объяснение: «s» означает поиск, «\ s» означает все пробелы, «*» означает ноль или много, «$» означает до конца строки, а «//» означает замену всех совпадений пустой строкой ,Вы можете удалить переводы строк с помощью
tr
:источник
С включенными расширенными функциями сопоставления с образцом в Bash (
shopt -s extglob
) вы можете использовать это:{trimmed##*( )}
удалить произвольное количество ведущих пробелов.
источник
/bin/sh -o posix
тоже работает но я с подозрениемtrimmed
? Это встроенная вещь или переменная, которая обрезается?источник
read
будет хранить в переменной по ее имени $ 1 урезанную версию ее значения $ {! 1}trim() { while [[ $# -gt 0 ]]; do read -rd '' $1 <<<"${!1}"; shift; done; }
read -rd '' str <<<"$str"
подойдет.Есть много ответов, но я все еще верю, что мой только что написанный сценарий стоит упомянуть, потому что:
"$*"
объединяет несколько аргументов, используя один пробел. если вы хотите обрезать и вывести только первый аргумент, используйте"$1"
вместоСценарий:
Применение:
Вывод:
источник
[\ \t]
[[:space:]]
бы как в одном из других ответов: stackoverflow.com/a/3352015/3968618Вы можете использовать старую школу
tr
. Например, это возвращает количество измененных файлов в репозитории git, пробелы удалены.источник
Это сработало для меня:
Чтобы поместить это в меньшее количество строк для того же результата:
источник
${var##Pattern}
получения более подробной информации. Кроме того, этот сайт объясняет шаблоны bash . Таким образом,##
средства удаляют данный шаблон спереди, а%%
средства удаляют данный шаблон сзади.+( )
Часть представляет собой шаблон , и это означает «один или более вхождение в пространстве»ИЛИ
ИЛИ
ИЛИ
ИЛИ
Опираясь на опыт Москита ...
ИЛИ
источник
Я видел сценарии, которые просто используют переменные для выполнения работы:
Пробелы автоматически объединяются и обрезаются. Нужно быть осторожным с метасимволами оболочки (потенциальный риск инъекции).
Я бы также рекомендовал всегда подставлять переменные в кавычки в условных выражениях оболочки:
поскольку что-то вроде -o или другого содержимого в переменной может изменить ваши тестовые аргументы.
источник
$xyz
с ,echo
что делает пробельную коалесцирующее, не переменная назначению. Чтобы сохранить усеченное значение в переменной в вашем примере, вы должны будете использоватьxyz=$(echo -n $xyz)
. Кроме того, этот подход подвержен потенциально нежелательному расширению пути (globbing).xyz
переменной НЕ обрезается.источник
echo $(echo "1 2 3")
(с двумя пробелами между 1, 2 и 3).Я бы просто использовал sed:
а) Пример использования однострочной строки
Вывод:
б) Пример использования многострочной строки
Вывод:
в) Последнее замечание:
если вам не нравится использовать функцию, для однострочной строки вы можете просто использовать команду «легче запомнить», например:
Пример:
Вывод:
Использование вышеперечисленного в многострочных строках также будет работать , но, пожалуйста, обратите внимание, что оно также сократит любой завершающий / ведущий внутренний множественный пробел, как заметил GuruM в комментариях.
Вывод:
Поэтому, если вы не возражаете, оставьте эти пробелы, пожалуйста, используйте функцию в начале моего ответа!
d) ОБЪЯСНЕНИЕ синтаксиса sed «найти и заменить» в многострочных строках, используемых внутри функции trim:
источник
Вот функция trim (), которая урезает и нормализует пробел
И еще один вариант, который использует регулярные выражения.
источник
*
символ во входной строке будет разверните все файлы и папки в текущей рабочей папке. Наконец, если для $ IFS установлено значение не по умолчанию, обрезка может не работать (хотя это легко исправить, добавивlocal IFS=$' \t\n'
). Обрезка ограничена следующими формами пробелов: пробелы\t
и\n
символы.if
строку с:if [[ "$trimmed" =~ ' '*([^ ]|[^ ].*[^ ])' '* ]]
. Наконец, подход касается только пробелов, а не других форм пробелов (см. Мой следующий комментарий).if
строку на:[[ "$trimmed" =~ [[:space:]]*([^[:space:]]|[^[:space:]].*[^[:space:]])[[:space:]]* ]]
Используйте AWK:
источник
$stripped_version=
echo $ var | awk '{gsub (/ ^ + | + $ /, "")} 1'``Назначения игнорируют начальные и конечные пробелы и как таковые могут быть использованы для обрезки:
источник
echo "$var"
чтобы увидеть значение с пробелами.var=$(echo $var)
но я не рекомендую это. Другие решения, представленные здесь, являются предпочтительными.Это не имеет проблемы с нежелательным сглаживанием, также, внутреннее пустое пространство не изменяется (при условии, что
$IFS
установлено значение по умолчанию, которое есть' \t\n'
).Он читает до первой новой строки (и не включает ее) или до конца строки, в зависимости от того, что наступит раньше, и удаляет любое сочетание начальных и конечных пробелов и
\t
символов. Если вы хотите сохранить несколько строк (а также убрать начальные и конечные новые строки), используйтеread -r -d '' var << eof
вместо этого; заметьте, однако, что, если ваш ввод будет содержать\neof
, он будет отключен непосредственно перед. (Другие формы пробелов, а именно\r
,\f
и\v
, не удаляются, даже если вы добавляете их в $ IFS.)источник
Чтобы удалить пробелы и табуляции слева направо, введите:
cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-word.html
источник
Это удалит все пробелы из вашей строки,
/
заменяет первое вхождение и//
все вхождения пробелов в строке. Т.е. заменяются все пробелы - ничегоисточник
Это самый простой метод, который я видел. Он использует только Bash, это всего несколько строк, регулярное выражение простое и соответствует всем формам пробелов:
Вот пример скрипта для тестирования:
источник
^[[:space:]]*(.*[^[:space:]])?[[:space:]]*$
Python имеет функцию,
strip()
которая работает идентично PHPtrim()
, поэтому мы можем просто сделать небольшой встроенный Python, чтобы сделать легко понятную утилиту для этого:Это урезает начальные и конечные пробелы (включая переводы строки).
источник
источник
Я обнаружил, что мне нужно добавить некоторый код из грязного
sdiff
вывода, чтобы очистить его:Это удаляет завершающие пробелы и другие невидимые символы.
источник
Удаление пробелов в один пробел:
источник