Sed veya awk ile belirli bir satır numarasına bir satır ekle


146

Ben 8 satırında bir metin eklemek için başka bir komut dosyası ile değiştirmek gereken bir komut dosyası var.

: Adlı Project_Name=sowstestbir dosyaya eklenecek dize start.

Awk ve sed kullanmaya çalıştım, ama benim komutum bozuldu.

Yanıtlar:


231
sed -i '8i8 This is Line 8' FILE

8. hatta ekler

8 This is Line 8

FILE dosyasına

-i glenn jackman tarafından yapılan yorumlarda belirtildiği gibi, doğrudan dosyaya dosya, stdout çıktısı yok.


3
Evet, -i anahtarı GNU-sed'e özgüdür.
kullanıcı bilinmiyor

1
Hayır. -İ, "belirtilen dosyayı yerinde değiştir" anlamına gelir. Insert-append, -i-switch'den bağımsız olarak '8isomething' ve '8asomething' ile elde edilir.
kullanıcı bilinmiyor

11
mac kullanıcıları: homebrew ile brew install gnu-sedve sonra bunu kullanıngsed
cwd

4
Bu süper kullanışlı! Çizginin başına boşluk eklemem için yine de var mı? Sed, ilk boşluğa dikkat
etmiyor

9
@elju: Evet, ters eğik çizgi ile maskelemek: sed '8i\ 8 This is Line 8' FILE.
kullanıcı bilinmiyor


19

OS X / macOS / FreeBSD sed

-iBayrak MacOS üzerinde farklı çalışır sedGNU daha sed.

MacOS / OS X'te kullanmanın yolu:

sed -i '' '8i\
8 This is Line 8' FILE

Daha man 1 sedfazla bilgi için bakınız .


18

awk cevabı

awk -v n=8 -v s="Project_Name=sowstest" 'NR == n {print s} {print}' file > file.new

@glenn jackman #define SERVER@"http://10.35.42.54/ms0.8"Belirli bir satıra girmem gerekiyor . Bunu nasıl başarabilirim?
Nevin Raj Victor

1
Bence Nevin sadece ters eğik çizgiler ile dizesindeki tırnaklardan kaçmak gerekiyor
Chris Koknat

@waLLe, awk'ın nasıl çalıştığının güzel bir açıklaması olan awk bilgi sayfası ile başlayın . Burada 2 "koşul {eylem}" çiftim var, ikincisinin durumu yok, bu da eylemin her kayıt için gerçekleştirildiği anlamına geliyor. Okumayı bitirdikten ve hala sorularınız olduğunda bana bildirin.
glenn jackman

@glennjackman neredeyse orada .. sadece bulamadım: dosya> file.new
w411 3

"dosya" awk'ın üzerinde çalıştığı dosyanın adını gösterir. awk çıktısının "file.new" adlı dosyada saklanması >için kabuk yönlendirme sembolüdür.
glenn jackman

16

POSIX'i sed(ve örneğin OS X'leri sed, sedaşağıdaki) ibir ters eğik çizgi ve bir yeni satır izlemelidir. Ayrıca en azından OS sedX'ler eklenen metinden sonra yeni satır içermez:

$ seq 3|gsed '2i1.5'
1
1.5
2
3
$ seq 3|sed '2i1.5'
sed: 1: "2i1.5": command i expects \ followed by text
$ seq 3|sed $'2i\\\n1.5'
1
1.52
3
$ seq 3|sed $'2i\\\n1.5\n'
1
1.5
2
3

Bir satırı değiştirmek için, sayısal bir adresle c(değiştir) veya s(değiştir) komutlarını kullanabilirsiniz:

$ seq 3|sed $'2c\\\n1.5\n'
1
1.5
3
$ seq 3|gsed '2c1.5'
1
1.5
3
$ seq 3|sed '2s/.*/1.5/'
1
1.5
3

Kullanan alternatifler awk:

$ seq 3|awk 'NR==2{print 1.5}1'
1
1.5
2
3
$ seq 3|awk '{print NR==2?1.5:$0}'
1
1.5
3

awkile iletilen değişkenlerdeki ters eğik çizgileri yorumlar, -vancak aşağıdakileri kullanarak geçirilen değişkenlerde değil ENVIRON:

$ seq 3|awk -v v='a\ba' '{print NR==2?v:$0}'
1
a
3
$ seq 3|v='a\ba' awk '{print NR==2?ENVIRON["v"]:$0}'
1
a\ba
3

Her ikisi de ENVIRON ve -vPOSIX tarafından tanımlanır.


7

Perl çözümleri:

hızlı ve kirli:

perl -lpe 'print "Project_Name=sowstest" if $. == 8' file

  • -l yeni satırları çıkarır ve tekrar ekler, "\ n" ihtiyacını ortadan kaldırır
  • -p Girdi dosyası üzerinde döngüler, her satırı yazdırma
  • -e kodu tek tırnak içinde yürütür

$. satır numarası

adlandırılmış argümanlar kullanarak @ glenn'in awk çözümüne eşdeğerdir:

perl -slpe 'print $s if $. == $n' -- -n=8 -s="Project_Name=sowstest" file

  • -s temel argüman ayrıştırıcısını etkinleştirir
  • -- -n ve -s öğelerinin standart perl bağımsız değişken ayrıştırıcısı tarafından ayrıştırılmasını engeller

konumsal komut argümanları:

perl -lpe 'BEGIN{$n=shift; $s=shift}; print $s if $. == $n' 8 "Project_Name=sowstest" file

Ortam Değişkenleri:

setenv n 8 ; setenv s "Project_Name=sowstest"
echo $n ; echo $s
perl -slpe 'print $ENV{s} if $. == $ENV{n}' file

ENV tüm ortam değişkenlerini içeren karma değerdir

Bağımsız değişkenleri% o ​​hash değerine ayrıştırmak için getopt:

perl -MGetopt::Std -lpe 'BEGIN{getopt("ns",\%o)}; print $o{s} if $. == $o{n}' -- -n 8 -s "Project_Name=sowstest" file

Getopt :: Uzun ve uzun seçenek isimleri

perl -MGetopt::Long -lpe 'BEGIN{GetOptions(\%o,"line=i","string=s")}; print $o{string} if $. == $o{line}' -- --line 8 --string "Project_Name=sowstest" file

Getopt önerilen standart kütüphane çözümüdür.
Bu, tek satırlık perl betikleri için aşırı olabilir, ancak yapılabilir


2
Tüm bunları açıklamak ve çok güzel bir şekilde ortaya koymak için zaman ayırdığınız için Chris size şükür, ama vay bu yüzden perl'i sevmiyorum.
16'da testere

5

GNU olmayan SunOS'ta olanlar için aşağıdaki kod yardımcı olacaktır:

sed '1i\^J
line to add' test.dat > tmp.dat
  • ^ J, ^ V + ^ J ile eklenir
  • '1i'den sonra yeni satırı ekleyin.
  • \ Satırın son karakteri OLMALIDIR.
  • Komutun ikinci kısmı ikinci bir satırda olmalıdır.

5

sed -e '8iProject_Name=sowstest' -i start GNU sed kullanma

Örnek çalışma:

[root@node23 ~]# for ((i=1; i<=10; i++)); do echo "Line #$i"; done > a_file
[root@node23 ~]# cat a_file
Line #1
Line #2
Line #3
Line #4
Line #5
Line #6
Line #7
Line #8
Line #9
Line #10
[root@node23 ~]# sed -e '3ixxx inserted line xxx' -i a_file 
[root@node23 ~]# cat -An a_file 
     1  Line #1$
     2  Line #2$
     3  xxx inserted line xxx$
     4  Line #3$
     5  Line #4$
     6  Line #5$
     7  Line #6$
     8  Line #7$
     9  Line #8$
    10  Line #9$
    11  Line #10$
[root@node23 ~]# 
[root@node23 ~]# sed -e '5ixxx (inserted) "line" xxx' -i a_file
[root@node23 ~]# cat -n a_file 
     1  Line #1
     2  Line #2
     3  xxx inserted line xxx
     4  Line #3
     5  xxx (inserted) "line" xxx
     6  Line #4
     7  Line #5
     8  Line #6
     9  Line #7
    10  Line #8
    11  Line #9
    12  Line #10
[root@node23 ~]# 

$Ekleme işleminden sonra 3. satırdaki iz nereden geliyor?
jww

Bu geliyor -Abayrağına cat:)
jno

eklemek istediğiniz dize tırnak işaretleri, parantez vb. içeriyorsa ne olur?
Anentropik

Yukarıdaki metnin güncellenmesine bakın. Bu, bu karakterlerden uygun şekilde kaçmanız gerektiği anlamına gelir.
jno

0

sed -i "" -e $ '4 a \\ n''Project_Name = sowstest' başlat

  • Bu satır macOS'ta iyi çalışır
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.