Her satırın başına bir önek dizesi ekleyin


334

Aşağıdaki gibi bir dosya var:

line1
line2
line3

Ve almak istiyorum:

prefixline1
prefixline2
prefixline3

Bir Ruby senaryosu yazabilirdim, ama ihtiyacım yoksa daha iyi.

prefixiçerir /. /opt/workdir/Örneğin bir yoldur .

Yanıtlar:


527
# If you want to edit the file in-place
sed -i -e 's/^/prefix/' file

# If you want to create a new file
sed -e 's/^/prefix/' file > file.new

Eğer prefixiçeriyorsa /, değil başka bir karakter kullanabilirsiniz prefixya da kaçmaya /böylece, sedkomut olur

's#^#/opt/workdir#'
# or
's/^/\/opt\/workdir/'

1
@benjamin, cevabınızı zaten iptal etmiştim, ancak bunun sedgibi hafif görevleri tercih ederim . "Önek" biliniyorsa, "önek" ten olmayan bir karakter seçmek çok kolaydır.
Alok Singhal

1
sedBir boru hattında da kullanabileceğinizi unutmayın foo | sed -e 's/^/x /' | bar.
14'te zigg

1
@ Dataman cool. Başka bir yol olurdu sed -e '2,$s/^/prefix/'.
Alok Singhal

1
@BinChen /benzeri \/(tek tırnaklı dizelerde) veya \\/(çift tırnaklı dizelerde)

8
sed -e 's/$/postfix/' fileHer satırın sonuna dize eklemek istiyorsanız kullanın .
Brian

121
awk '$0="prefix"$0' file > new_file

Perl ile (yerinde değiştirme):

perl -pi 's/^/prefix/' file

8
: Bir boru / akımı veya değişkeniprtinf "$VARIABLE\n" | awk '$0="prefix"$0'
ThorSummoner

2
Büyük bir dosya (12 G) ile awkraporları awk: out of memory in readrec 1 source line number 1, ancak çözümü ile sedbaşarıyla tamamlar.
jrm

33

Vim'i Ex modunda kullanabilirsiniz:

ex -sc '%s/^/prefix/|x' file
  1. % tüm satırları seç

  2. s değiştirmek

  3. x kaydet ve kapat


1
Benim için dosyayı vim ve tipte açıyorum :%s/^/prefix/, çünkü bu strateji birçok durumda yararlı oluyor
Frank Bryce

23

Ön ekiniz biraz karmaşıksa, sadece bir değişkene koyun:

prefix=path/to/file/

Sonra, bu değişkeni iletir ve awk'ın onunla baş etmesine izin verirsiniz:

awk -v prefix="$prefix" '{print prefix $0}' input_file.txt


6

Kabuğu kullanma:

#!/bin/bash
prefix="something"
file="file"
while read -r line
do
 echo "${prefix}$line"
done <$file > newfile
mv newfile $file

5

Moreutils tskomutunu kullanarak okunabilir bir oneliner çözümü

$ cat file | ts prefix | tr -d ' '

Ve adım adım nasıl türetildi:

# Step 0. create the file

$ cat file
line1
line2
line3
# Step 1. add prefix to the beginning of each line

$ cat file | ts prefix
prefix line1
prefix line2
prefix line3
# Step 2. remove spaces in the middle

$ cat file | ts prefix | tr -d ' '
prefixline1
prefixline2
prefixline3

'ts' varsayılan olarak birçok Linux dağıtımına yüklenmez. Ayrıca, bu cevabın sonundaki "tr -d ''" in aşağı oyu, sadece 'ts' tarafından eklenen alanı değil, satırlardaki tüm boşlukları kaldıracaktır
Tim Bird

3

Her ne kadar pierr'ın bu endişe olduğunu düşünmese de, aynı anda birkaç uyarı günlüğünü izlemek ve her satırın ilgili günlüğünün adını ekleyerek bir dosyanın canlı "kuyruğundan" çıktıyı geciktirmeyecek bir çözüme ihtiyacım vardı. .

Ne yazık ki, sed, kes, vb. Çok fazla tamponlama getirdi ve beni en güncel çizgileri görmekten alıkoydu. Steven Penny'nin öneri kullanmak -sseçeneğinl ilgi çekiciydi ve testler, beni ilgilendiren istenmeyen tamponlamayı tanıtmadığını kanıtladı.

Bununla birlikte nl, istenmeyen satır numaralarını çıkarma arzusuyla ilgili olarak birkaç sorun vardı (estetiği umursamasanız bile, ekstra sütunların kullanılmasının istenmeyen olacağı durumlar olabilir). İlk olarak, sayıları ayırmak için "kes" komutunu kullanarak tamponlama sorununu yeniden ortaya çıkarır, böylece çözümü bozar. İkincisi, "-w1" kullanmak yardımcı olmaz, çünkü bu satır numarasını tek bir sütunla sınırlamaz - daha fazla basamak gerektiğinden daha da genişler.

Bunu başka bir yerde yakalamak istiyorsanız hoş değil, ama tam olarak yapmam gerekmediği için (her şey zaten günlük dosyalarına yazılmaktaydı, sadece bir kerede gerçek zamanlı olarak birkaçını izlemek istedim), en iyisi satır numaralarını kaybetmenin ve benim önekimin olması, -sdizgiyi satır başı (CR veya ^ M veya Ctrl-M) ile başlatmaktı . Yani mesela:

#!/bin/ksh

# Monitor the widget, framas, and dweezil
# log files until the operator hits <enter>
# to end monitoring.

PGRP=$$

for LOGFILE in widget framas dweezil
do
(
    tail -f $LOGFILE 2>&1 |
    nl -s"^M${LOGFILE}>  "
) &
sleep 1
done

read KILLEM

kill -- -${PGRP}

1
kullanmak -uarabelleğe önlemek için sed seçeneği.
Bryan Larsen

2
Arabelleğe alma arabelleğe alma / stdbuf ile kapatılabilir, bkz. Unix.stackexchange.com/q/25372/6205
myroslav

2

Ed kullanarak:

ed infile <<'EOE'
,s/^/prefix/
wq
EOE

Her hat için bu yerine, ( ,), çizgi (başlangıcı ^ile birlikte) prefix. wqkaydeder ve çıkar.

Yeni dize eğik çizgi içeriyorsa sbunun yerine farklı bir ayırıcı kullanabiliriz :

ed infile <<'EOE'
,s#^#/opt/workdir/#
wq
EOE

Ben EOEparametre genişlemesini önlemek için burada-doc sınırlayıcı ("ed sonu") alıntı var . Bu örnekte, alıntı yapılmadan da işe yarayacaktır, ancak $ed betiğinizde hiç varsa sürprizleri önlemek iyi bir uygulamadır .


2

& (Girişin desenle eşleşen tüm kısmı ”kullanılarak):

cat in.txt | sed -e "s/.*/prefix&/" > out.txt

VEYA geri referansları kullanarak:

cat in.txt | sed -e "s/\(.*\)/prefix\1/" > out.txt

2
  1. Bunu backreference tekniğini kullanarak da yapabilirsiniz.

    sed -i.bak 's/\(.*\)/prefix\1/' foo.txt
    
  2. Bunun gibi awk ile de kullanabilirsiniz

    awk '{print "prefix"$0}' foo.txt > tmp && mv tmp foo.txt
    

1

İşte bu cevabınsed yaklaşımını kullanarak tamamlanmış bir örnek :

$ cat /path/to/some/file | prefix_lines "WOW: "

WOW: some text
WOW: another line
WOW: more text

prefix_lines

function show_help()
{
  IT=$(CAT <<EOF
    Usage: PREFIX {FILE}

    e.g.

    cat /path/to/file | prefix_lines "WOW: "

      WOW: some text
      WOW: another line
      WOW: more text
  )
  echo "$IT"
  exit
}

# Require a prefix
if [ -z "$1" ]
then
  show_help
fi

# Check if input is from stdin or a file
FILE=$2
if [ -z "$2" ]
then
  # If no stdin exists
  if [ -t 0 ]; then
    show_help
  fi
  FILE=/dev/stdin
fi

# Now prefix the output
PREFIX=$1
sed -e "s/^/$PREFIX/" $FILE

2
PREFIXEğik çizgi gibi silmeye özel karakterler içeriyorsa bu çalışmaz .
josch

İyi bir nokta ... Eğik çizgi kullandığınızı fark ederseniz, burada ayrıntılı olarak açıklandığı gibi sed kısmı ile farklı bir sınırlayıcı kullanabilirsiniz, bu da aramalarda kullanmanıza izin verir. Diğer özel sed karakterleri bir eğik çizgi ile kaçarak konabilir, örneğinprefix_lines \*
Brad Parks

0

BSD / OSX sistemlerindeki insanlar lamiçin, laminat için kısa adlı yardımcı program vardır . lam -s prefix filene istersen yapacak. Boru hatlarında kullanıyorum, örneğin:

find -type f -exec lam -s "{}: " "{}" \; | fzf

... tüm dosyaları bulacaktır, her birinde lam çalıştırarak her dosyaya kendi dosya adının önekini verin. (Ve aramak için çıkışı fzf'ye pompalayın.)


Haklısın, bu sadece BSD komutu gibi görünüyor. POSIX bunu macun ile değiştirdi, ancak macunun tam bir ayırıcı dize ekleme özelliği yok. Cevabımı güncelleyeceğim.
Ray
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.