Sed ile takip eden beyaz boşluklar nasıl kaldırılır?


113

Bir dosyadan sondaki beyaz boşluğu kaldıran basit bir kabuk betiğim var. Bu komut dosyasını (geçici bir dosya oluşturmadan) daha kompakt hale getirmenin herhangi bir yolu var mı?

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

2
Sen kullanabilirsiniz mvyerine catve rm. catYine de neden böyle kullanıyorsun ? Neden kullanmıyorsun cp?
sonraki duyuruya kadar duraklatıldı.


1
Windows'ta
sed'deki


catOrijinal dosyanın üzerine yazmak için kullanmanın , orijinal dosyadaki mvverileri gerçekten değiştireceğini unutmayın (yani, sabit bağlantıları kesmeyecektir). sed -iBirçok çözümde önerildiği gibi kullanmak bunu yapmaz. IOW, yaptığınız şeyi yapmaya devam edin.
William Pursell

Yanıtlar:


157

Sen yerde seçeneğinde kullanabilirsiniz -iarasında sedLinux ve Unix için:

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

İfadenin tOSX'teki sonları sileceğini unutmayın ( gsedbu sorunu önlemek için kullanabilirsiniz ). Bunları BSD'de de silebilir.

Gsed'iniz yoksa, OSX'te doğru (ancak okunması zor) sed sözdizimi burada:

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

Üç tek tırnaklı dize, nihayetinde tek bir bağımsız değişken / ifadede birleştirilir. Bash'de bitiştirme operatörü yoktur, sadece aralarda boşluk bırakmadan dizeleri birbiri ardına yerleştirirsiniz.

Bu, $'\t'bash'de değişmez sekme karakteri olarak çözülür ( ANSI-C tırnaklama kullanılarak ), böylece sekme ifadeye doğru şekilde birleştirilir.


1
sed: Not a recognized flag: i
Makinemde

2
hm. sondaki tüm "t" leri kaldırması açısından da hatalı :)
Good Person

2
"sed: Tanınan bir bayrak değil: i -" Bu, OSX'te olur. Mac'lerde -i'den sonra yedekleme dosyası için bir uzantı eklemeniz gerekir. örneğin: sed -i .bak 's / [\ t] * $ //' $ 1
Aimon Bustardo

1
@GoodPerson Şaka yapmıyorsanız, muhtemelen kaçmayı unutursunuz t:) \tzaten bilmeyenler için bir sekmedir.
Sean Allred

2
@SeanAllred şaka yapmıyordu: GNU sed kullanmadığınız sürece tamamen bozuk (ki bu pek çok başka şekilde bozulmuştur)
Good Person

59

En azından Mountain Lion'da, Viktor'un cevabı, bir satırın sonunda olduğunda 't' karakterini de kaldıracaktır. Aşağıdaki bu sorunu düzeltir:

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

1
Sed'im ayrıca -E"genişletilmiş (modern) normal ifadeler" de istiyordu
Jared Beck

OS X'te bir cazibe gibi çalışıyor. Çok teşekkür ederim.
jww

1
codaddict'in cevabı OS X'te (şimdi macOS) aynı soruna sahip. Bu, bu platformdaki tek çözümdür.
Franklin Yu

sedEl Capitan'da @JaredBeck Mine yoktu.
Franklin Yu

19

Bu -iseçeneği önerdiği için codaddict'e teşekkürler .

Aşağıdaki komut Snow Leopard'daki sorunu çözer

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


7
@Acrollet'in dediği gibi, \tGNU sed dışında sed ile kullanamazsınız ve gerçek bir harf olarak yorumlanır t. Komut yalnızca işe yarıyor gibi görünüyor, bunun nedeni muhtemelen tdosyanızın sonundaki boşlukta TAB veya cümlenin sonunda bir yer olmamasıdır . ''Bir yedek son ek belirtmeden kullanılması tavsiye edilmez.
Scrutinizer

13

Ayrıca 1 $ teklif etmek en iyisidir:

sed -i.bak 's/[[:blank:]]*$//' "$1"

5
var1="\t\t Test String trimming   "
echo $var1
Var2=$(echo "${var1}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
echo $Var2

1
Hey, ihtiyacım olan buydu! Gönderilen diğer sed çözümleri, bash betiğimdeki borulu (ve borulu ve borulu ...) değişken atamayla bütünleştirme sorununa sahipti, ancak sizinki kutudan çıktı.
Eric L.

4

.Bashrc dosyamda OSX ve Linux altında çalışan bir komut dosyası var (sadece 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
}

buna eklediğim:

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
}

3

Verimlilik arayanlar için (işlenecek çok sayıda dosya veya çok büyük dosyalar), +bunun yerine tekrar operatörünü kullanmak *, komutu iki katından daha hızlı hale getirir.

GNU sed ile:

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

Ayrıca başka bir şeyi de hızlı bir şekilde kıyasladım: [ \t]bunun yerine kullanmak [[:space:]]da süreci önemli ölçüde hızlandırıyor (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

1

Sadece eğlence için:

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

0

Özelinde ise sed, -idiğerleri zaten belirtmiştik, bu seçeneğin uzak ve uzak basit ve sanest biridir.

Daha genel bir durumda, spongegelen moreutilsbu özel olarak çok bu kadar dosya üzerine yazarak kendisine takılmadan gelen işleme adımı tutmak için tasarlanmış bir bakıma, bunu işleme sonucu içeren bir dosya yerine sağlar: toplama, ne istediğinizi tam olarak yapar üzerinde çalışmak. spongeMan sayfasını alıntılamak için :

sponge standart girdiyi okur ve belirtilen dosyaya yazar. Bir kabuk yönlendirmesinin aksine, sünger çıktı dosyasını yazmadan önce tüm girdisini emer. Bu, aynı dosyadan okuyan ve bu dosyaya yazan ardışık düzenlerin oluşturulmasına izin verir.

https://joeyh.name/code/moreutils/


-1

En az bir boşluk olmayan karakter içeren satırlardan yalnızca beyaz boşlukları (benim durumumda boşluklar ve sekmeler) çıkarmak için (bu şekilde boş girintili satırlara dokunulmaz):

sed -i -r 's/([^ \t]+)[ \t]+$/\1/' "$file"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.