web-dev-qa-db-ja.com

Bash変数から空白を削除する方法

このコードを含むシェルスクリプトがあります。

var=`hg st -R "$path"`
if [ -n "$var" ]; then
    echo $var
fi

hg stは常に少なくとも1つの改行文字を出力するため、条件付きコードは常に実行されます。

  • $varから空白を取り除く簡単な方法はありますか( _ php _trim()のように)。

または

  • この問題に対処する標準的な方法はありますか?

sed または _ awk _ を使用できますが、この問題にはもっと優雅な解決策があると思います。

770
too much php

先頭、末尾、および中間の空白を含む変数を定義しましょう。

FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16

すべての空白を削除する方法(trでは[:space:]で表される):

FOO=' test test test '
FOO_NO_WHITESPACE="$(echo -e "${FOO}" | tr -d '[:space:]')"
echo -e "FOO_NO_WHITESPACE='${FOO_NO_WHITESPACE}'"
# > FOO_NO_WHITESPACE='testtesttest'
echo -e "length(FOO_NO_WHITESPACE)==${#FOO_NO_WHITESPACE}"
# > length(FOO_NO_WHITESPACE)==12

先頭の空白だけを削除する方法:

FOO=' test test test '
FOO_NO_LEAD_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//')"
echo -e "FOO_NO_LEAD_SPACE='${FOO_NO_LEAD_SPACE}'"
# > FOO_NO_LEAD_SPACE='test test test '
echo -e "length(FOO_NO_LEAD_SPACE)==${#FOO_NO_LEAD_SPACE}"
# > length(FOO_NO_LEAD_SPACE)==15

末尾の空白のみを削除する方法:

FOO=' test test test '
FOO_NO_TRAIL_SPACE="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_TRAIL_SPACE='${FOO_NO_TRAIL_SPACE}'"
# > FOO_NO_TRAIL_SPACE=' test test test'
echo -e "length(FOO_NO_TRAIL_SPACE)==${#FOO_NO_TRAIL_SPACE}"
# > length(FOO_NO_TRAIL_SPACE)==15

先頭と末尾のスペースを削除する方法 - sedsをチェーニングします。

FOO=' test test test '
FOO_NO_EXTERNAL_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_EXTERNAL_SPACE='${FOO_NO_EXTERNAL_SPACE}'"
# > FOO_NO_EXTERNAL_SPACE='test test test'
echo -e "length(FOO_NO_EXTERNAL_SPACE)==${#FOO_NO_EXTERNAL_SPACE}"
# > length(FOO_NO_EXTERNAL_SPACE)==14

あるいは、あなたのbashがそれをサポートしていれば、echo -e "${FOO}" | sed ...sed ... <<<${FOO}に置き換えることができます。

FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
908
MattyV

簡単な答えは:

echo "   lol  " | xargs

Xargs はあなたのためにトリミングを行います。これは1つのコマンド/プログラムで、パラメータはありません。トリミングされた文字列をそのまま返します。

注:これは内部スペースを削除しないので、"foo bar"は同じままです。 "foobar"にはなりません。

792
makevoid

ワイルドカード と呼ばれるBash組み込み関数のみを使用する解決策があります。

var="    abc    "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"   
echo "===$var==="

これは関数に包まれた同じものです:

trim() {
    local var="$*"
    # remove leading whitespace characters
    var="${var#"${var%%[![:space:]]*}"}"
    # remove trailing whitespace characters
    var="${var%"${var##*[![:space:]]}"}"   
    echo -n "$var"
}

あなたは引用符で囲まれた形式でトリミングする文字列を渡します。例えば。:

trim "   abc   "

このソリューションのいいところは、POSIX準拠のシェルならどれでも動作するということです。

参照

290
bashfu

Bashは パラメータ展開 と呼ばれる機能を持ちます。これはとりわけ、いわゆる パターン に基づく文字列置換を可能にします(パターンは正規表現に似ていますが、根本的な違いと制限があります)。 [flussenceの元の行:Bashには正規表現がありますが、隠れています:]

以下は、変数値から all 空白を削除する方法を示しています(内部からでも)。

$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef
68
user42092

先頭と末尾のスペースを1つ削除する

trim()
{
    local trimmed="$1"

    # Strip leading space.
    trimmed="${trimmed## }"
    # Strip trailing space.
    trimmed="${trimmed%% }"

    echo "$trimmed"
}

例えば:

test1="$(trim " one leading")"
test2="$(trim "one trailing ")"
test3="$(trim " one leading and one trailing ")"
echo "'$test1', '$test2', '$test3'"

出力:

'one leading', 'one trailing', 'one leading and one trailing'

ストリップ すべて 前後のスペース

trim()
{
    local trimmed="$1"

    # Strip leading spaces.
    while [[ $trimmed == ' '* ]]; do
       trimmed="${trimmed## }"
    done
    # Strip trailing spaces.
    while [[ $trimmed == *' ' ]]; do
        trimmed="${trimmed%% }"
    done

    echo "$trimmed"
}

例えば:

test4="$(trim "  two leading")"
test5="$(trim "two trailing  ")"
test6="$(trim "  two leading and two trailing  ")"
echo "'$test4', '$test5', '$test6'"

出力:

'two leading', 'two trailing', 'two leading and two trailing'
44
Brian Cain

文字列の先頭と末尾(行末文字を含む)からすべてのスペースを削除するには、次の手順を実行します。

echo $variable | xargs echo -n

これにより重複したスペースも削除されます。

echo "  this string has a lot       of spaces " | xargs echo -n

「この文字列にはスペースがたくさんあります」

40
rkachach

echoを使えば簡単にトリミングできます。

foo=" qsdqsd qsdqs q qs   "

# Not trimmed
echo \'$foo\'

# Trim
foo=`echo $foo`

# Trimmed
echo \'$foo\'
36
VAmp

globbing のBashガイドセクションから

パラメータ展開でextglobを使用する

 #Turn on extended globbing  
shopt -s extglob  
 #Trim leading and trailing whitespace from a variable  
x=${x##+([[:space:]])}; x=${x%%+([[:space:]])}  
 #Turn off extended globbing  
shopt -u extglob  

これは、関数にラップされた同じ機能です(注:functionに渡される入力文字列を引用符で囲む必要があります)。

trim() {
    # Determine if 'extglob' is currently on.
    local extglobWasOff=1
    shopt extglob >/dev/null && extglobWasOff=0 
    (( extglobWasOff )) && shopt -s extglob # Turn 'extglob' on, if currently turned off.
    # Trim leading and trailing whitespace
    local var=$1
    var=${var##+([[:space:]])}
    var=${var%%+([[:space:]])}
    (( extglobWasOff )) && shopt -u extglob # If 'extglob' was off before, turn it back off.
    echo -n "$var"  # Output trimmed string.
}

使用法:

string="   abc def ghi  ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");  
echo "$trimmed";

サブシェルで実行するように関数を変更しても、extglobの現在のShellオプションを調べる必要はありません。現在のShellに影響を与えずに設定することができます。これは機能を非常に単純化します。位置変数も「その場で」更新するので、ローカル変数も必要ありません。

trim() {
    shopt -s extglob
    set -- "${1##+([[:space:]])}"
    printf "%s" "${1%%+([[:space:]])}" 
}

そう:

$ s=$'\t\n \r\tfoo  '
$ shopt -u extglob
$ shopt extglob
extglob         off
$ printf ">%q<\n" "$s" "$(trim "$s")"
>$'\t\n \r\tfoo  '<
>foo<
$ shopt extglob
extglob         off
35
GuruM

Bashの拡張パターンマッチング機能を有効にすると(shopt -s extglob)、これを使うことができます。

{trimmed##*( )}

任意の量の先行スペースを削除します。

24
Mooshu

私はいつもsedでやった

  var=`hg st -R "$path" | sed -e 's/  *$//'`

もっとエレガントな解決策があれば、誰かがそれを投稿してほしいです。

20
Paul Tomblin

trで改行を削除することができます。

var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
    echo $var
done
20
Adam Rosenfield
# Trim whitespace from both ends of specified parameter

trim () {
    read -rd '' $1 <<<"${!1}"
}

# Unit test for trim()

test_trim () {
    local foo="$1"
    trim foo
    test "$foo" = "$2"
}

test_trim hey hey &&
test_trim '  hey' hey &&
test_trim 'ho  ' ho &&
test_trim 'hey ho' 'hey ho' &&
test_trim '  hey  ho  ' 'hey  ho' &&
test_trim $'\n\n\t hey\n\t ho \t\n' $'hey\n\t ho' &&
test_trim $'\n' '' &&
test_trim '\n' '\n' &&
echo passed
17
flabdablet

たくさんの答えがありますが、私は今でも私が書いたばかりのスクリプトが言及される価値があると信じています:

  • それは正常にシェルbash/dash/busyboxシェルでテストされました
  • とても小さい
  • それは外部コマンドに依存せず、フォークする必要はありません( - >高速と低リソースの使用)
  • それは期待通りに動作します:
    • 先頭と末尾から all スペースとタブを削除しますが、それ以上は削除しません。
    • 重要:文字列の途中から何も削除されません(他の多くの回答では削除されます)。改行でも残ります
    • special:"$*"は1つのスペースを使って複数の引数を結合します。最初の引数だけをトリミングして出力したい場合は、代わりに"$1"を使用してください。
    • 一致するファイル名パターンなどに問題がなければ

スクリプト:

trim() {
  local s2 s="$*"
  # note: the brackets in each of the following two lines contain one space
  # and one tab
  until s2="${s#[   ]}"; [ "$s2" = "$s" ]; do s="$s2"; done
  until s2="${s%[   ]}"; [ "$s2" = "$s" ]; do s="$s2"; done
  echo "$s"
}

使用法:

mystring="   here     is
    something    "
mystring=$(trim "$mystring")
echo ">$mystring<"

出力:

>here     is
    something<
11
Daniel Alder

あなたは昔のtrを使うことができます。例えば、これはgitレポジトリ内の空白を取り除いた、修正されたファイルの数を返します。

MYVAR=`git ls-files -m|wc -l|tr -d ' '`
11
pojo

これは私のために働いた:

text="   trim my edges    "

trimmed=$text
trimmed=${trimmed##+( )} #Remove longest matching series of spaces from the front
trimmed=${trimmed%%+( )} #Remove longest matching series of spaces from the back

echo "<$trimmed>" #Adding angle braces just to make it easier to confirm that all spaces are removed

#Result
<trim my edges>

同じ結果を得るためにこれをより少ない行に置くには、

text="    trim my edges    "
trimmed=${${text##+( )}%%+( )}
9
gMale
# Strip leading and trailing white space (new line inclusive).
trim(){
    [[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]]
    printf "%s" "$BASH_REMATCH"
}

OR

# Strip leading white space (new line inclusive).
ltrim(){
    [[ "$1" =~ [^[:space:]].* ]]
    printf "%s" "$BASH_REMATCH"
}

# Strip trailing white space (new line inclusive).
rtrim(){
    [[ "$1" =~ .*[^[:space:]] ]]
    printf "%s" "$BASH_REMATCH"
}

# Strip leading and trailing white space (new line inclusive).
trim(){
    printf "%s" "$(rtrim "$(ltrim "$1")")"
}

OR

# Strip leading and trailing specified characters.  ex: str=$(trim "$str" $'\n a')
trim(){
    if [ "$2" ]; then
        trim_chrs="$2"
    else
        trim_chrs="[:space:]"
    fi

    [[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

OR

# Strip leading specified characters.  ex: str=$(ltrim "$str" $'\n a')
ltrim(){
    if [ "$2" ]; then
        trim_chrs="$2"
    else
        trim_chrs="[:space:]"
    fi

    [[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"]) ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

# Strip trailing specified characters.  ex: str=$(rtrim "$str" $'\n a')
rtrim(){
    if [ "$2" ]; then
        trim_chrs="$2"
    else
        trim_chrs="[:space:]"
    fi

    [[ "$1" =~ ^(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

# Strip leading and trailing specified characters.  ex: str=$(trim "$str" $'\n a')
trim(){
    printf "%s" "$(rtrim "$(ltrim "$1" "$2")" "$2")"
}

OR

モスキットのexprの汚染に基づいて構築...

# Strip leading and trailing white space (new line inclusive).
trim(){
    printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$"`"
}

OR

# Strip leading white space (new line inclusive).
ltrim(){
    printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)"`"
}

# Strip trailing white space (new line inclusive).
rtrim(){
    printf "%s" "`expr "$1" : "^\(.*[^[:space:]]\)[[:space:]]*$"`"
}

# Strip leading and trailing white space (new line inclusive).
trim(){
    printf "%s" "$(rtrim "$(ltrim "$1")")"
}
9
NOYB

私はスクリプトがただ仕事をするために変数代入を使うのを見ました:

$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar

空白は自動的に合体してトリミングされます。シェルのメタキャラクタ(潜在的な注入リスク)に注意する必要があります。

シェル条件式では、常に変数置換を二重引用符で囲むことをお勧めします。

if [ -n "$var" ]; then

変数の中の-oや他の内容のようなものがあなたのテスト引数を修正するかもしれないので。

8
MykennaC
var='   a b c   '
trimmed=$(echo $var)
7
ultr

単にsedを使います。

function trim
{
    echo "$1" | sed -n '1h;1!H;${;g;s/^[ \t]*//g;s/[ \t]*$//g;p;}'
}

a)単一行文字列の使用例

string='    wordA wordB  wordC   wordD    '
trimmed=$( trim "$string" )

echo "GIVEN STRING: |$string|"
echo "TRIMMED STRING: |$trimmed|"

出力:

GIVEN STRING: |    wordA wordB  wordC   wordD    |
TRIMMED STRING: |wordA wordB  wordC   wordD|

b)複数行ストリングの使用例

string='    wordA
   >wordB<
wordC    '
trimmed=$( trim "$string" )

echo -e "GIVEN STRING: |$string|\n"
echo "TRIMMED STRING: |$trimmed|"

出力:

GIVEN STRING: |    wordAA
   >wordB<
wordC    |

TRIMMED STRING: |wordAA
   >wordB<
wordC|

c)最後のメモ:
もしあなたが関数を使いたくなければ、 単一行文字列に対して あなたは単純に "覚えやすい"コマンドを使うことができます。

echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'

例:

echo "   wordA wordB wordC   " | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'

出力:

wordA wordB wordC

上記の 複数行の文字列を使用しても同じように動作します が、GuruMがコメントで気づいたように、末尾/先頭の内部複数スペースもカットしますのでご注意ください。

string='    wordAA
    >four spaces before<
 >one space before<    '
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'

出力:

wordAA
>four spaces before<
>one space before<

それで、あなたがそれらのスペースを保つことを気にするならば、私の答えの始めに関数を使ってください!

d)説明 関数trimの内部で使用される複数行の文字列に対するsed構文 "find and replace"の/

sed -n '
# If the first line, copy the pattern to the hold buffer
1h
# If not the first line, then append the pattern to the hold buffer
1!H
# If the last line then ...
$ {
    # Copy from the hold to the pattern buffer
    g
    # Do the search and replace
    s/^[ \t]*//g
    s/[ \t]*$//g
    # print
    p
}'
7
Luca Borrione

代入は先頭と末尾の空白を無視するので、それを使ってトリミングすることができます。

$ var=`echo '   hello'`; echo $var
hello
6
evanx

左から最初のWordまでのスペースとタブを削除するには、次のように入力します。

echo "     This is a test" | sed "s/^[ \t]*//"

cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-Word.html

5
Steven Penny

これは空白をトリミングして正規化するtrim()関数です。

#!/bin/bash
function trim {
    echo $*
}

echo "'$(trim "  one   two    three  ")'"
# 'one two three'

そして正規表現を使うもう一つの変種。

#!/bin/bash
function trim {
    local trimmed="$@"
    if [[ "$trimmed" =~ " *([^ ].*[^ ]) *" ]]
    then 
        trimmed=${BASH_REMATCH[1]}
    fi
    echo "$trimmed"
}

echo "'$(trim "  one   two    three  ")'"
# 'one   two    three'
5

AWKを使用:

echo $var | awk '{gsub(/^ +| +$/,"")}1'
5
ghostdog74

これはあなたの文字列からすべての空白を削除します、

 VAR2="${VAR2//[[:space:]]/}"

/は文字列内の最初の出現箇所を置換し、//は空白文字の出現箇所をすべて置換します。すなわちすべての空白はに置き換えられます - 何も

4
Alpesh Gediya

これが私が見た中で最も簡単な方法です。これはBashだけを使います、それはほんの数行で、正規表現は単純です、そしてそれはすべての形式の空白にマッチします:

if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then 
    test=${BASH_REMATCH[1]}
fi

これをテストするためのサンプルスクリプトは次のとおりです。

test=$(echo -e "\n \t Spaces and tabs and newlines be gone! \t  \n ")

echo "Let's see if this works:"
echo
echo "----------"
echo -e "Testing:${test} :Tested"  # Ugh!
echo "----------"
echo
echo "Ugh!  Let's fix that..."

if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then 
    test=${BASH_REMATCH[1]}
fi

echo
echo "----------"
echo -e "Testing:${test}:Tested"  # "Testing:Spaces and tabs and newlines be gone!"
echo "----------"
echo
echo "Ah, much better."
4
blujay

これは、不要なグロビングの問題はありません。また、内部の空白は変更されません($IFSがデフォルトの' \t\n'に設定されていると仮定)。

最初の改行まで(そしてそれを含まない)まで、または文字列の最後までのいずれか早い方まで読み取り、先頭と末尾のスペースと\t文字の組み合わせを取り除きます。複数の行を保存したい(そして先頭と末尾の改行も削除したい)場合は、代わりにread -r -d '' var << eofを使用してください。ただし、入力に\neofが含まれている場合は、直前に切り捨てられます。 (他の形式の空白、つまり\r\f、および\vは、$ IFSに追加しても 削除されます。)

read -r var << eof
$var
eof
4
Gregor

Pythonには、PHPのstrip()と同じように機能するtrim()という関数があります。そのため、これを理解しやすいユーティリティを作成するために、少しインラインのPythonを実行するだけで済みます。

alias trim='python -c "import sys; sys.stdout.write(sys.stdin.read().strip())"'

これは先頭と末尾の空白(改行を含む)を削除します。

$ x=`echo -e "\n\t   \n" | trim`
$ if [ -z "$x" ]; then echo hi; fi
hi
3
brownhead

trim()は空白文字(とタブ、印刷不可能な文字。私は簡単のため空白文字だけを考えています)を削除します。私のバージョンのソリューション:

var="$(hg st -R "$path")" # I often like to enclose Shell output in double quotes
var="$(echo "${var}" | sed "s/\(^ *\| *\$\)//g")" # This is my suggestion
if [ -n "$var" ]; then
 echo "[${var}]"
fi

'sed'コマンドは、先頭と末尾の空白のみを削除しますが、最初のコマンドにパイプで渡すこともできます。

var="$(hg st -R "$path" | sed "s/\(^ *\| *\$\)//g")"
if [ -n "$var" ]; then
 echo "[${var}]"
fi
3
Avenger
#!/bin/bash

function trim
{
    typeset trimVar
    eval trimVar="\${$1}"
    read trimVar << EOTtrim
    $trimVar
EOTtrim
    eval $1=\$trimVar
}

# Note that the parameter to the function is the NAME of the variable to trim, 
# not the variable contents.  However, the contents are trimmed.


# Example of use:
while read aLine
do
    trim aline
    echo "[${aline}]"
done < info.txt



# File info.txt contents:
# ------------------------------
# ok  hello there    $
#    another  line   here     $
#and yet another   $
#  only at the front$
#$



# Output:
#[ok  hello there]
#[another  line   here]
#[and yet another]
#[only at the front]
#[]
3
Razor5900

クリーンアップするために、厄介なsdiffの出力からコードを追加する必要があることがわかりました。

sdiff -s column1.txt column2.txt | grep -F '<' | cut -f1 -d"<" > c12diff.txt 
sed -n 1'p' c12diff.txt | sed 's/ *$//g' | tr -d '\n' | tr -d '\t'

これは末尾のスペースや他の見えない文字を削除します。

3
user1186515

つかいます:

trim() {
    local orig="$1"
    local trmd=""
    while true;
    do
        trmd="${orig#[[:space:]]}"
        trmd="${trmd%[[:space:]]}"
        test "$trmd" = "$orig" && break
        orig="$trmd"
    done
    printf -- '%s\n' "$trmd"
}
  • 改行を含め、あらゆる種類の空白に対して機能します。
  • Shoptを変更する必要はありません。
  • 改行を含めて内部の空白を保持します。

単体テスト(手動レビュー用):

#!/bin/bash

. trim.sh

enum() {
    echo "   a b c"
    echo "a b c   "
    echo "  a b c "
    echo " a b c  "
    echo " a  b c  "
    echo " a  b  c  "
    echo " a      b  c  "
    echo "     a      b  c  "
    echo "     a  b  c  "
    echo " a  b  c      "
    echo " a  b  c      "
    echo " a N b  c  "
    echo "N a N b  c  "
    echo " Na  b  c  "
    echo " a  b  c N "
    echo " a  b  c  N"
}

xcheck() {
    local testln result
    while IFS='' read testln;
    do
        testln=$(tr N '\n' <<<"$testln")
        echo ": ~~~~~~~~~~~~~~~~~~~~~~~~~ :" >&2
        result="$(trim "$testln")"
        echo "testln='$testln'" >&2
        echo "result='$result'" >&2
    done
}

enum | xcheck
3
Alois Mahdal

以下の機能を作成しました。可搬性のあるprintfがどのようなものかはわかりませんが、この解決策の利点は、文字コードを追加することによって「空白」を正確に指定できることです。

    iswhitespace()
    {
        n=`printf "%d\n" "'$1'"`
        if (( $n != "13" )) && (( $n != "10" )) && (( $n != "32" )) && (( $n != "92" )) && (( $n != "110" )) && (( $n != "114" )); then
            return 0
        fi
        return 1
    }

    trim()
    {
        i=0
        str="$1"
        while (( i < ${#1} ))
        do
            char=${1:$i:1}
            iswhitespace "$char"
            if [ "$?" -eq "0" ]; then
                str="${str:$i}"
                i=${#1}
            fi
            (( i += 1 ))
        done
        i=${#str}
        while (( i > "0" ))
        do
            (( i -= 1 ))
            char=${str:$i:1}
            iswhitespace "$char"
            if [ "$?" -eq "0" ]; then
                (( i += 1 ))
                str="${str:0:$i}"
                i=0
            fi
        done
        echo "$str"
    }

#Call it like so
mystring=`trim "$mystring"`
3
cmeub

スペースを1つのスペースに削除する:

(text) | fmt -su
2
gardziol

IFS変数が別のものに設定されているとき、私はスクリプトから空白を削除する必要がありました。 Perl に頼ってトリックをしました:

# trim() { echo $1; } # This doesn't seem to work, as it's affected by IFS

trim() { echo "$1" | Perl -p -e 's/^\s+|\s+$//g'; }

strings="after --> , <-- before,  <-- both -->  "

OLD_IFS=$IFS
IFS=","
for str in ${strings}; do
  str=$(trim "${str}")
  echo "str= '${str}'"
done
IFS=$OLD_IFS
2
TrinitronX
var="  a b  "
echo "$(set -f; echo $var)"

>a b
2
davide

この単純なBashを使う パラメータ展開

$ x=" a z     e r ty "
$ echo "START[${x// /}]END"
START[azerty]END
2
Gilles Quenot

つかいます:

var=`expr "$var" : "^\ *\(.*[^ ]\)\ *$"`

これは先頭と末尾のスペースを削除し、最も基本的な解決策です、と私は思います。 Bashには組み込まれていませんが、 'expr'はcoreutilsの一部なので、 sed または _ awk _ のように少なくともスタンドアロンのユーティリティは必要ありません。

2
moskit

これはフロントとエンドの複数のスペースをトリミングする

whatever=${whatever%% *}

whatever=${whatever#* }

2
gretelmk2

さらに別の解決策 - 単体テストを使用する stdinから$IFSを削除し、任意の入力区切り文字($'\0'を含む)で動作する。

ltrim()
{
    # Left-trim $IFS from stdin as a single line
    # $1: Line separator (default NUL)
    local trimmed
    while IFS= read -r -d "${1-}" -u 9
    do
        if [ -n "${trimmed+defined}" ]
        then
            printf %s "$REPLY"
        else
            printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
        fi
        printf "${1-\x00}"
        trimmed=true
    done 9<&0

    if [[ $REPLY ]]
    then
        # No delimiter at last line
        if [ -n "${trimmed+defined}" ]
        then
            printf %s "$REPLY"
        else
            printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
        fi
    fi
}

rtrim()
{
    # Right-trim $IFS from stdin as a single line
    # $1: Line separator (default NUL)
    local previous last
    while IFS= read -r -d "${1-}" -u 9
    do
        if [ -n "${previous+defined}" ]
        then
            printf %s "$previous"
            printf "${1-\x00}"
        fi
        previous="$REPLY"
    done 9<&0

    if [[ $REPLY ]]
    then
        # No delimiter at last line
        last="$REPLY"
        printf %s "$previous"
        if [ -n "${previous+defined}" ]
        then
            printf "${1-\x00}"
        fi
    else
        last="$previous"
    fi

    right_whitespace="${last##*[!$IFS]}"
    printf %s "${last%$right_whitespace}"
}

trim()
{
    # Trim $IFS from individual lines
    # $1: Line separator (default NUL)
    ltrim ${1+"$@"} | rtrim ${1+"$@"}
}
1
l0b0

コマンドの結果(数値)をテストする必要がありましたが、結果の変数にスペースといくつかの印刷できない文字が含まれているようです。したがって、「トリム」の後でも、比較は誤っていました。変数から数値部分を抽出することで解決しました:

numerical_var=$(echo ${var_with_result_from_command} | grep -o "[0-9]*")
0
Olivier Meurice