Yanıtlar:
-FSeçenek bir argüman gerekir: -F,örneğin.
awkKomut dosyasının sonu , parametrelerin geri kalanıyla birlikte bir (boşluk karakteri) ile ayrılmalıdır .
Alan ayırıcı ise ,ve bunu korumak istiyorsanız ve sütun sayısı sabit ve 11'e eşit veya daha düşükse, şunu deneyin:
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file. Yani GNU yeni bir sürümü söyledi awkbunu desteklemek için: gawk -i inplace '{blah blah}' file.
mv newfile filekullanabilirsiniz cat newfile > file ; rm -f newfile- bu inode ve izinlerini korur file.
mktempgeçici dosya adlarını komut dosyalarına kodlamak yerine kullanmak genellikle iyi bir fikirdir . örneğintf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
Daha kısa çözüm
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
,+Tüm awksürümlerde çalışıp çalışmayacağından emin değilim , ancak en azından GNU -cawk'de , aynı zamanda uyumluluk modunda çalışıyor.
Açıklama:
$(NF+1)=$7: önce satırın sonuna 7. alan ekliyoruz ( $12=$7bu durumda olabilir)$7="": sonraki adımda 7. alan silinir (ancak çevresindeki sınırlayıcılar kalır)$0=$0birden çok virgülün alan ayırıcısı olarak ele alındığı tüm kaydı (yoluyla ) yeniden ayarlamamız gerekir (bu -F',+', burada +bir veya daha fazla kez yapılır) ve ayrıca $1=$1önceden ayarlanmış çıktı alanını kullanarak satırı yeniden oluşturmaya zorlamak için geçerli kaydı yeniden düzenlememiz gerekir. ayırıcı (bir seçenekle ayarlanır -v OFS=,)1Örnek girdi:
1,2,3,4,5,6,7,8,9,10,11
çıktı
1,2,3,4,5,6,8,9,10,11,7
,+çalışmalıdır.
all,ball,call,,,fall→ all,ball,call,fall). (2) $(NF+1)=$7akıllı bir yaklaşımdır. IMHO, $0 = $0 OFS $7biraz daha net, sadece birkaç karakter daha uzun ve aynı şeyi yapıyor gibi görünüyor. Kodunuzla $0 = $0 OFS $7aynı şeyi yapmayan bir durum düşünebiliyor musunuz?
$0=$0 OFS $7büyük olasılıkla aynıdır $(NF+1)=$7, ancak genel olarak değil, yalnızca kodun geri kalanında değişiklik olmaz.
OFS=Alanlarla ayırıcı olmadan yazdırıyorsanız , $7bir değişkenin değerini kolayca kaydedebilir, $7boş olarak ayarlayabilir ve çizgiyi ve değişkeni doğrudan yazdırabilirsiniz. Tüm alanları belirtmenize gerek yoktur:
$ cat file
1,2,3,4,5,6,7,8
$ awk -F, -vOFS= '{k=$7; $7=""; print $0,k}' file
12345687
Muhtemelen demek istediniz:
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awkTek tırnakları hiç görmediğini biliyorsun OFS='', değil mi? Sadece yazabilirsiniz OFS=; tamamen aynı.
Özellikle awk kullanmak istediğinizi söylemediniz ve tarafından sağlanan düzenlemeyi kullanmak istediğinizi söylediniz sed -i, işte bir sed -ivaryant. Genellikle awksütunlarla çalışmak için daha iyidir, ancak bu tercih ettiğim bir durumdur sed, çünkü doğal olarak rasgele sayıda sütun işler.
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
Açıklama:
-r genişletilmiş normal ifadeleri seçer, böylece çok fazla ters eğik çizgiden kaçınırızTabii ki bu, virgülleri tırnak içinde saklayan (veya daha da kötüsü, onlardan kaçan) dosyalarla çalışmaz, ancak awk bazı ciddi akrobasi olmadan da bunu yapmaz. Eğer böyle bir sorun varsa birlikte daha iyi olurdu perlmodülü Text:CSVveya pythonmodül csv.
Birkaç awkvaryant (dosyanızın değişkenin içinde olduğu varsayılarak $file)
Burada tüm sütunlar için döngü yapabilir, alan ayırıcısı (OFS) ile yazdırabilir ve satır sonundaki kayıt sonlandırıcıyı (ORS) yazdırabilirsiniz.
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"
Burada bir normal ifade ve gensub()işlev kullanarak
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
öldürme 7 inci alanını ve satırın sonunda yazdırmadan.
$0 tüm kayıt $nn inci rekor NF geçerli satırın Alan Sayısıdır OFS çıktı dosyalanmış ayırıcıORS çıkış kayıt sonlandırıcısı1awk trueve default ( $0) yazdırmak için söyleyecek hiledir .Güncelleme ...
Neredeyse 7'den aşağıdaki tüm sütunları kayması mümkündür, unutmak inci biri.
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7daha sağlam olurdu "," $7. (2) ", " $7Sorunun OP'nin virgüllerden sonra boşluk istemediğini belirttiği sürece bunun yanlış olduğuna inanıyorum . (Ve, giriş verilerinde virgüllerden sonra boşluklar $7olsaydı, zaten bir boşlukla başlayacaktı ve fazladan bir tane ekleyecektin.)
OFS $7sadece daha sağlam değil, daha da genel ( "acele atık yapar" )
^Hata ile karşılaşıldı komutların özel bölümünü gösterir.