web-dev-qa-db-ja.com

sedで末尾の空白を削除するにはどうすればよいですか?

ファイルから末尾の空白を削除する単純なシェルスクリプトがあります。 (一時ファイルを作成せずに)このスクリプトをよりコンパクトにする方法はありますか?

sed 's/[ \t]*$//' $1 > $1__.tmp
cat $1__.tmp > $1
rm $1__.tmp
92
Viktor

-iオプションを提案してくれたcodaddictに感謝します。

次のコマンドは、Snow Leopardの問題を解決します

sed -i '' -e's/[ \t]*$//' "$1"
18
Viktor

LinuxおよびUnixでは、インプレースオプション-i of sedを使用できます。

sed -i 's/[ \t]*$//' "$1"

この式は、OSXで末尾のtを削除することに注意してください(この問題を回避するには、gsedを使用できます)。 BSDでも削除される可能性があります。

Gsedをお持ちでない場合、OSXでの正しい(しかし読みにくい)sed構文は次のとおりです。

sed -i '' -E 's/[ '$'\t'']+$//' "$1"

3つの一重引用符で囲まれた文字列は、最終的に1つの引数/式に連結されます。 bashには連結演算子はありません。文字列を次々に配置し、間にスペースを入れないでください。

$'\t'は( ANSI-Cの引用 を使用して)bashのリテラルタブ文字として解決されるため、タブは式に正しく連結されます。

139
codaddict

少なくともMountain Lionでは、Viktorの回答は、行末にある文字「t」も削除します。以下は、この問題を修正します。

sed -i '' -e's/[[:space:]]*$//' "$1"
55
acrollet

また、$ 1を引用することをお勧めします。

sed -i.bak 's/[[:blank:]]*$//' "$1"
13
Scrutinizer
var1="\t\t Test String trimming   "
echo $var1
Var2=$(echo "${var1}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
echo $Var2
4

効率(処理する多数のファイル、または巨大なファイル)を求める人にとっては、+の代わりに*繰り返し演算子を使用すると、コマンドが2倍以上高速になります。

GNU sedの場合:

sed -Ei 's/[ \t]+$//' "$1"
sed -i 's/[ \t]\+$//' "$1"   # The same without extended regex

また、すぐに他の何かをベンチマークしました。[ \t]の代わりに[[:space:]]を使用すると、プロセスが大幅にスピードアップします(GNU sed v4.4):

sed -Ei 's/[ \t]+$//' "$1"

real    0m0,335s
user    0m0,133s
sys 0m0,193s

sed -Ei 's/[[:space:]]+$//' "$1"

real    0m0,838s
user    0m0,630s
sys 0m0,207s

sed -Ei 's/[ \t]*$//' "$1"

real    0m0,882s
user    0m0,657s
sys 0m0,227s

sed -Ei 's/[[:space:]]*$//' "$1"

real    0m1,711s
user    0m1,423s
sys 0m0,283s
3
yolenoyer

OSXおよびLinuxで動作するスクリプトが.bashrcにあります(bashのみ!)

function trim_trailing_space() {
  if [[ $# -eq 0 ]]; then
    echo "$FUNCNAME will trim (in place) trailing spaces in the given file (remove unwanted spaces at end of lines)"
    echo "Usage :"
    echo "$FUNCNAME file"
    return
  fi
  local file=$1
  unamestr=$(uname)
  if [[ $unamestr == 'Darwin' ]]; then
    #specific case for Mac OSX
    sed -E -i ''  's/[[:space:]]*$//' $file
  else
    sed -i  's/[[:space:]]*$//' $file
  fi
}

私が追加するもの:

SRC_FILES_EXTENSIONS="js|ts|cpp|c|h|hpp|php|py|sh|cs|sql|json|ini|xml|conf"

function find_source_files() {
  if [[ $# -eq 0 ]]; then
    echo "$FUNCNAME will list sources files (having extensions $SRC_FILES_EXTENSIONS)"
    echo "Usage :"
    echo "$FUNCNAME folder"
    return
  fi
  local folder=$1

  unamestr=$(uname)
  if [[ $unamestr == 'Darwin' ]]; then
    #specific case for Mac OSX
    find -E $folder -iregex '.*\.('$SRC_FILES_EXTENSIONS')'
  else
    #Rhahhh, lovely
    local extensions_escaped=$(echo $SRC_FILES_EXTENSIONS | sed s/\|/\\\\\|/g)
    #echo "extensions_escaped:$extensions_escaped"
    find $folder -iregex '.*\.\('$extensions_escaped'\)$'
  fi
}

function trim_trailing_space_all_source_files() {
  for f in $(find_source_files .); do trim_trailing_space $f;done
}
2
Pascal T.

楽しみのためだけに:

#!/bin/bash

FILE=$1

if [[ -z $FILE ]]; then
   echo "You must pass a filename -- exiting" >&2
   exit 1
fi

if [[ ! -f $FILE ]]; then
   echo "There is not file '$FILE' here -- exiting" >&2
   exit 1
fi

BEFORE=`wc -c "$FILE" | cut --delimiter=' ' --fields=1`

# >>>>>>>>>>
sed -i.bak -e's/[ \t]*$//' "$FILE"
# <<<<<<<<<<

AFTER=`wc -c "$FILE" | cut --delimiter=' ' --fields=1`

if [[ $? != 0 ]]; then
   echo "Some error occurred" >&2
else
   echo "Filtered '$FILE' from $BEFORE characters to $AFTER characters"
fi
1
David Tonhofer