Как удалить конечные пробелы с помощью sed?
У меня есть простой скрипт, который удаляет конечные пробелы из файла. Есть ли способ сделать этот скрипт более компактным (без создания временного файла)?
sed 's/[ t]*$//' > __.tmp
cat __.tmp >
rm __.tmp
9 ответов:
вы можете использовать опцию на месте
-i
наsed
для Linux и Unix:sed -i 's/[ \t]*$//' ""
имейте в виду, что выражение удалит трейлинг
t
' s на OSX (вы можете использоватьgsed
чтобы избежать этой проблемы). Он также может удалить их на BSD.если у вас нет gsed, вот правильный (но трудночитаемый) синтаксис sed на OSX:
sed -i '' -E 's/[ '$'\t'']+$//' ""
три строки в одинарных кавычках в конечном итоге объединяются в один аргумент/выражение. Нет никакой конкатенации оператор в bash, вы просто размещаете строки один за другим без пробелов между ними.
The
$'\t'
разрешает как литеральный символ табуляции в bash (используя ANSI-C цитирование), поэтому вкладка правильно объединена в выражение.
по крайней мере, на Mountain Lion ответ Виктора также удалит символ "t", когда он находится в конце строки. Следующие исправления этой проблемы:
sed -i '' -e's/[[:space:]]*$//' ""
спасибо codaddict за предложение .
следующая команда решает проблему на Snow Leopard
sed -i '' -e's/[ \t]*$//' ""
var1="\t\t Test String trimming " echo $var1 Var2=$(echo "${var1}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') echo $Var2
просто для удовольствия:
#!/bin/bash FILE= 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= 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= 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]+$//' "" sed -i 's/[ \t]\+$//' "" # The same without extended regex
Я также быстро сравнил что-то еще: используя
[ \t]
вместо[[:space:]]
также значительно ускоряет процесс (GNU sed v4. 4):sed -Ei 's/[ \t]+$//' "" real 0m0,335s user 0m0,133s sys 0m0,193s sed -Ei 's/[[:space:]]+$//' "" real 0m0,838s user 0m0,630s sys 0m0,207s sed -Ei 's/[ \t]*$//' "" real 0m0,882s user 0m0,657s sys 0m0,227s sed -Ei 's/[[:space:]]*$//' "" real 0m1,711s user 0m1,423s sys 0m0,283s