如何删除尾部空白与sed?

我有一个简单的shell脚本,从文件中删除尾随空白。 有没有办法让这个脚本更紧凑(不创build临时文件)?

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

您可以使用sed for Linux和Unix的就地选项-i

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

请注意expression式会删除OS X上的结尾t (你可以使用gsed来避免这个问题)。 它也可能在BSD上删除它们。

至less在“山狮”上,维克托的回答也会在字符结尾处删除字符“t”。 以下修复了这个问题:

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

感谢codaddictbuild议-i选项。

以下命令解决了Snow Leopard上的问题

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

最好还引用$ 1:

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

只是为了好玩:

 #!/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 

我在.bashrc中有一个脚本,可以在OSX和Linux下运行(仅限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 } 

对于那些寻求效率(许多文件处理,或大文件),使用+重复运算符,而不是*使命令两倍以上的速度。

使用GNU sed:

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

我也快速地做了一些基准testing:使用[ \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 

为了只删除至less有一个非空白字符的行(在我的例子中是空格和制表符)(这样空白的缩进行不被触及):

 sed -i -r 's/([^ \t]+)[ \t]+$/\1/' "$file"