Birden çok metin dosyasının 5. satırında bir dize nasıl değiştirilir?


22

Birden fazla metin dosyasının 5. satırını ( file1.txt, file2.txt, file3.txt, file4.txt ) tek bir terminal komutu kullanarak "Günaydın" dizesiyle değiştirmek istiyorum .

Tüm metin dosyaları benim üzerinde bulunur ~/Desktop.

Not: Masaüstümde 6 .txt dosyası var. Değişikliği yalnızca yukarıda belirtilen 4 metin dosyasına uygulamak istiyorum.

Yanıtlar:


40

İşte birkaç yaklaşım. Ayraç genişletme ( file{1..4}.txt) kullanıyorumfile1.txt file2.txt file3.txt file4.txt

  1. Perl

    perl -i -pe 's/.*/ Good Morning / if $.==5' file{1..4}.txt

    Açıklama:

    • -i: perlorijinal dosyaları değiştirerek yerinde dosyaları düzenlemeye neden olur .

      -iBir dosya uzantısı sonekiyle takip edilirse , değiştirilen her dosya için bir yedekleme oluşturulur. Ör: yürütme sırasında değiştirilmiş -i.bakbir file1.txt.bakif oluşturur file1.txt.

    • -p: giriş dosyasını satır satır okumak, komut dosyasını uygulamak ve yazdırmak anlamına gelir.

    • -e: bir komut dosyasını komut satırından geçirmenize olanak verir.

    • s/.*/ Good Morning /: Geçerli satırdaki ( .*) metni Günaydın ile değiştirilir.

    • $.Giriş dosyasının geçerli satır numarasını tutan özel bir Perl değişkenidir. Yani, sadece 5 satırda ile s/foo/bar/ if $.==5değiştirin demektir .foobar

  2. sed

    sed -i '5s/.*/ Good Morning /' file{1..4}.txt

    Açıklama:

    • -i: Bunun için perl, yerinde bir dosyayı düzenleyin.

    Varsayılan olarak, sedgiriş dosyasının her satırını yazdırır. 5s/pattern/replacement/5. satırda değiştirme ile araçları yerine model.

  3. awk

    for f in file{1..4}.txt; do 
        awk 'NR==5{$0=" Good Morning "}1;' "$f" > foobar && mv foobar "$f"; 
    done

    Açıklama:

    awk-iseçeneğe eşdeğer ¹ seçeneği yoktur ; bu foobar, orijinalin üzerine yazmak üzere yeniden adlandırılan geçici bir dosya ( ) oluşturmamız gerektiği anlamına gelir . Bash döngüsü , geçerli dosya adını olduğu gibi kaydederek for f in file{1..4}.txt; do ... ; doneher birinden geçer . In , geçerli satır numarası ve geçerli satırın içeriğidir. Bu nedenle, komut dosyası ( ) satırını yalnızca 5. satırda "Günaydın" ile değiştirir . ise "satırını basmak" şeklinde.file{1..4}.txt$fawkNR$0$01;awk

    ¹ yeni sürümler devnull onun gösterdi yok gibi cevap .

  4. coreutils

    for f in file{1..4}.txt; do 
        (head -4 "$f"; echo " Good Morning "; tail -n +6 "$f") > foobar && 
        mv foobar "$f"; 
    done 

    Açıklama:

    Döngü önceki bölümde açıklanmıştır.

    • head -4: ilk 4 satırı yazdır

    • echo " Good Morning ": "Günaydın" yazdırın

    • tail -n +6: 6. satırdan dosyanın sonuna kadar her şeyi yazdırabilirsiniz

    Bu ( )üç komutun etrafındaki parantezler, üçünün de çıktısını almanızı sağlar (yani, ilk 4 satır, ardından "Günaydın", sonra satırların kalanı) ve bunları bir dosyaya yönlendirirsiniz.


23

Kullanabilirsiniz sed:

sed '5s/^/Good morning /' file

Good morningbir dosyanın beşinci satırına eklenirdi .

5. satırdaki içeriği değiştirmek istiyorsanız, şunu söyleyin:

sed '5s/.*/Good morning/' file

Değişiklikleri dosyaya yerinde kaydetmek istiyorsanız, şu -iseçeneği kullanın:

sed -i '5s/.*/Good morning/' file

sedbir seferde birden fazla dosyayı işleyebilir. Komutun sonuna sadece daha fazla dosya adı ekleyebilirsiniz. Belirli dosyaları eşleştirmek için bash genişletmelerini de kullanabilirsiniz:

# manually specified
sed -i '5s/.*/Good morning/' file1.txt file2.txt file3.txt file4.txt

# wildcard: all files on the desktop
sed -i '5s/.*/Good morning/' ~/Desktop/*

# brace expansion: file1.txt, file2.txt, file3.txt, file4.txt
sed -i '5s/.*/Good morning/' file{1..4}.txt

Sen burada ayracı açılımları hakkında daha fazla bilgi bulabilirsiniz .


GNU awk sürüm 4.1.0 ve daha üstü , yerinde düzenlemeyi mümkün kılan bir uzantıyla gelir. Yani şöyle diyebilirsin:

gawk -i inplace 'NR==5{$0="Good morning"}7' file

Dosyadaki # 5 satırını değiştirmek için Good morning!


2

Python çözümü görmedim işte burada:

import sys
import os
def open_and_replace(filename):

    with open(filename) as read_file:
        temp = open("/tmp/temp.txt","w")
        for index,line in enumerate(read_file,1):
            if  index == 5:
                temp.write("NEW STRING\n")
            else:
                temp.write(line.strip() + "\n")
        temp.close()
    os.rename("/tmp/temp.txt",filename)

for file_name in sys.argv[1:]:
    open_and_replace(file_name)

Temel fikir, komut satırında argüman olarak verilen her dosya için geçici bir dosya yazıp her bir satırı orijinal dosyada numaralandırmamızdır. Satır dizini 5 ise, farklı olan satırları yazarız. Gerisi sadece eski dosyayı temp dosyası Demo ile değiştiriyor:

$> ls
file1.txt  file2.txt  file3.txt
$> cat file1.txt                                                               
line 1
line 2
line 3
line 4
GOOD MORNING
line 6
$> python ~/replace_5th_line.py file1.txt file2.txt  file3.txt                 
$> cat file1.txt                                                               
line 1
line 2
line 3
line 4
NEW STRING
line 6
$> cat file2.txt                                                               
line 1
line 2
line 3
line 4
NEW STRING
line 6

Aynı şey liste kavrama ile de sağlanabilir. Aşağıda aynı betiğin bir astarı bulunmaktadır:

cat /etc/passwd | python -c 'import sys; print "\n".join(["CUSTOM"  if index == 5 else line.strip() for index,line in enumerate(sys.stdin,1)])'

veya olmadan cat

python -c 'import sys; print "\n".join(["CUSTOM"  if index == 5 else line.strip() for index,line in enumerate(sys.stdin,1)])' < /etc/passwd

Orada kalan basitçe düzenlenmiş içeriğin çıktılarını başka bir dosyaya yönlendirmek. > output.txt


1

Vim'i Ex modunda kullanabilirsiniz:

for b in 1 2 3 4
do
  ex -sc '5c|Good Morning' -cx file"$b".txt
done
  1. 5 5. satırı seç

  2. c metni değiştir

  3. x değişiklik yapıldıysa yaz (varsa) ve istifa


0

Aşağıdaki, bu cevapta önerilen perl işlemini tamamlayan bir bash betiğidir.

Örnek:

/ Tmp / o

console:
  enabled:false

Ardından aşağıdakileri çalıştırın:

$ search_and_replace_on_line_of_file.sh false true 2 /tmp/it

ve dosya şimdi içeriyor

/ Tmp / o

console:
  enabled:true

search_and_replace_on_line_of_file.sh

function show_help()
{
  IT=$(CAT <<EOF

  usage: SEARCH REPLACE LINE_NUM FILE

  e.g. 

  false true 52 /tmp/it  -> replaces false with true on line 52 of file /tmp/it

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$4" ]
then
  show_help
fi

SEARCH_FOR=$1
REPLACE_WITH=$2
LINE_NO=$3
FILE_NAME=$4
perl -i -pe "s/$SEARCH_FOR/$REPLACE_WITH/ if $.==$LINE_NO" $FILE_NAME 
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.