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.
prefix
içerir /
. /opt/workdir/
Örneğin bir yoldur .
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.
prefix
içerir /
. /opt/workdir/
Örneğin bir yoldur .
Yanıtlar:
# 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 prefix
içeriyorsa /
, değil başka bir karakter kullanabilirsiniz prefix
ya da kaçmaya /
böylece, sed
komut olur
's#^#/opt/workdir#'
# or
's/^/\/opt\/workdir/'
sed
Bir boru hattında da kullanabileceğinizi unutmayın foo | sed -e 's/^/x /' | bar
.
sed -e '2,$s/^/prefix/'
.
sed -e 's/$/postfix/' file
Her satırın sonuna dize eklemek istiyorsanız kullanın .
awk '$0="prefix"$0' file > new_file
Perl ile (yerinde değiştirme):
perl -pi 's/^/prefix/' file
prtinf "$VARIABLE\n" | awk '$0="prefix"$0'
awk
raporları awk: out of memory in readrec 1 source line number 1
, ancak çözümü ile sed
başarıyla tamamlar.
Vim'i Ex modunda kullanabilirsiniz:
ex -sc '%s/^/prefix/|x' file
%
tüm satırları seç
s
değiştirmek
x
kaydet ve kapat
:%s/^/prefix/
, çünkü bu strateji birçok durumda yararlı oluyor
Perl'iniz varsa:
perl -pe 's/^/PREFIX/' input.file
Kabuğu kullanma:
#!/bin/bash
prefix="something"
file="file"
while read -r line
do
echo "${prefix}$line"
done <$file > newfile
mv newfile $file
Moreutils ts
komutunu 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
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 -s
seç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ı, -s
dizgiyi 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}
-u
arabelleğe önlemek için sed seçeneği.
Ed kullanarak:
ed infile <<'EOE'
,s/^/prefix/
wq
EOE
Her hat için bu yerine, ( ,
), çizgi (başlangıcı ^
ile birlikte) prefix
. wq
kaydeder ve çıkar.
Yeni dize eğik çizgi içeriyorsa s
bunun yerine farklı bir ayırıcı kullanabiliriz :
ed infile <<'EOE'
,s#^#/opt/workdir/#
wq
EOE
Ben EOE
parametre 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 .
Bunu backreference tekniğini kullanarak da yapabilirsiniz.
sed -i.bak 's/\(.*\)/prefix\1/' foo.txt
Bunun gibi awk ile de kullanabilirsiniz
awk '{print "prefix"$0}' foo.txt > tmp && mv tmp foo.txt
İş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
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
PREFIX
Eğik çizgi gibi silmeye özel karakterler içeriyorsa bu çalışmaz .
prefix_lines \*
BSD / OSX sistemlerindeki insanlar lam
için, laminat için kısa adlı yardımcı program vardır . lam -s prefix file
ne 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.)
sed
gibi hafif görevleri tercih ederim . "Önek" biliniyorsa, "önek" ten olmayan bir karakter seçmek çok kolaydır.