ฉันมีไฟล์ดังนี้:
line1
line2
line3
และฉันต้องการได้รับ:
prefixline1
prefixline2
prefixline3
ฉันสามารถเขียนสคริปต์ Ruby แต่ดีกว่าถ้าฉันไม่ต้องการ
prefix
/
จะมี มันเป็นเส้นทาง/opt/workdir/
ตัวอย่างเช่น
ฉันมีไฟล์ดังนี้:
line1
line2
line3
และฉันต้องการได้รับ:
prefixline1
prefixline2
prefixline3
ฉันสามารถเขียนสคริปต์ Ruby แต่ดีกว่าถ้าฉันไม่ต้องการ
prefix
/
จะมี มันเป็นเส้นทาง/opt/workdir/
ตัวอย่างเช่น
คำตอบ:
# 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
หากprefix
มี/
คุณสามารถใช้ตัวละครอื่น ๆ ที่ไม่ได้อยู่ในprefix
นั้นหรือหลบหนีไป/
ดังนั้นsed
คำสั่งจะกลายเป็น
's#^#/opt/workdir#'
# or
's/^/\/opt\/workdir/'
sed
foo | sed -e 's/^/x /' | bar
sed -e '2,$s/^/prefix/'
คือ
sed -e 's/$/postfix/' file
หากคุณต้องการเพิ่มสตริงที่ส่วนท้ายของแต่ละบรรทัด
คุณสามารถใช้ Vim ในโหมด Ex:
ex -sc '%s/^/prefix/|x' file
%
เลือกทุกบรรทัด
s
แทนที่
x
บันทึกและปิด
:%s/^/prefix/
เนื่องจากกลยุทธ์นี้จบลงด้วยการเป็นประโยชน์ในหลาย ๆ สถานการณ์
หากคำนำหน้าของคุณซับซ้อนเล็กน้อยให้ใส่ไว้ในตัวแปร:
prefix=path/to/file/
จากนั้นคุณผ่านตัวแปรนั้นและปล่อยให้ awk จัดการกับมัน
awk -v prefix="$prefix" '{print prefix $0}' input_file.txt
หากคุณมี Perl:
perl -pe 's/^/PREFIX/' input.file
ใช้เปลือก:
#!/bin/bash
prefix="something"
file="file"
while read -r line
do
echo "${prefix}$line"
done <$file > newfile
mv newfile $file
นี่เป็นโซลูชันts
ออนไลเนอร์ที่สามารถอ่านได้สูงโดยใช้คำสั่งจาก moreutils
$ cat file | ts prefix | tr -d ' '
และมันเป็นวิธีที่ได้รับทีละขั้นตอน:
# 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
ในขณะที่ฉันไม่คิดว่า Pierr มีข้อกังวลใจนี้ฉันต้องการโซลูชันที่จะไม่หน่วงเวลาเอาต์พุตจากส่วน "สด" ของไฟล์เนื่องจากฉันต้องการตรวจสอบบันทึกการแจ้งเตือนหลายรายการพร้อมกันโดยนำหน้าแต่ละบรรทัดด้วยชื่อของบันทึกที่เกี่ยวข้อง .
น่าเสียดายที่ sed ตัดและแนะนำการบัฟเฟอร์มากเกินไปและทำให้ฉันไม่เห็นบรรทัดปัจจุบันมากที่สุด ข้อเสนอแนะของ Steven Penny ในการใช้-s
ตัวเลือกnl
นั้นน่าสนใจและการทดสอบพิสูจน์ว่ามันไม่ได้แนะนำการบัฟเฟอร์ที่ไม่ต้องการที่เกี่ยวข้องกับฉัน
แม้ว่าจะมีปัญหาในการใช้งานสองสามประการnl
ที่เกี่ยวข้องกับความต้องการที่จะตัดหมายเลขบรรทัดที่ไม่ต้องการออก (แม้ว่าคุณจะไม่สนใจเกี่ยวกับสุนทรียภาพของมัน แต่อาจมีบางกรณีที่การใช้คอลัมน์พิเศษจะไม่เป็นที่ต้องการ) ขั้นแรกให้ใช้ "ตัด" เพื่อตัดตัวเลขออกใหม่แนะนำปัญหาบัฟเฟอร์ดังนั้นจึงทำให้การแก้ปัญหาเสียหาย ข้อที่สองการใช้ "-w1" ไม่ได้ช่วยเนื่องจากจะไม่ จำกัด จำนวนบรรทัดในคอลัมน์เดียว - มันจะกว้างขึ้นเมื่อต้องการตัวเลขเพิ่มเติม
มันไม่สวยเลยถ้าคุณต้องการจับภาพนี้ที่อื่น แต่เนื่องจากเป็นสิ่งที่ฉันไม่จำเป็นต้องทำ (ทุกอย่างถูกเขียนไปยังล็อกไฟล์แล้วฉันแค่อยากจะดูหลายรายการพร้อมกันแบบเรียลไทม์) ที่ดีที่สุด วิธีที่จะสูญเสียหมายเลขบรรทัดและมีเพียงคำนำหน้าของฉันคือการเริ่มต้น-s
สายที่มีผลตอบแทนการขนส่ง (CR หรือ ^ M หรือ Ctrl-M) ตัวอย่างเช่น:
#!/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
ตัวเลือกเพื่อ sed เพื่อหลีกเลี่ยงการบัฟเฟอร์
ใช้ ed:
ed infile <<'EOE'
,s/^/prefix/
wq
EOE
ทดแทนนี้สำหรับแต่ละบรรทัด ( ,
) จุดเริ่มต้นของบรรทัด ( ^
) prefix
ด้วย wq
บันทึกและออก
หากสตริงการแทนที่มีเครื่องหมายทับเราสามารถใช้ตัวคั่นอื่นs
แทน:
ed infile <<'EOE'
,s#^#/opt/workdir/#
wq
EOE
ฉันยกเครื่องหมายตัวคั่น here-doc EOE
("end of ed") เพื่อป้องกันการขยายพารามิเตอร์ ในตัวอย่างนี้มันจะทำงานอย่างไม่มีเงื่อนไขเช่นกัน แต่เป็นวิธีปฏิบัติที่ดีในการป้องกันความประหลาดใจหากคุณเคยมี$
สคริปต์ ed ของคุณ
การใช้ & (ส่วนทั้งหมดของอินพุตที่ตรงกับรูปแบบ”):
cat in.txt | sed -e "s/.*/prefix&/" > out.txt
หรือใช้การอ้างอิงย้อนกลับ:
cat in.txt | sed -e "s/\(.*\)/prefix\1/" > out.txt
นอกจากนี้คุณยังสามารถทำได้โดยใช้เทคนิคการย้อนกลับ
sed -i.bak 's/\(.*\)/prefix\1/' foo.txt
คุณสามารถใช้กับ awk แบบนี้ได้
awk '{print "prefix"$0}' foo.txt > tmp && mv tmp foo.txt
นี่คือตัวอย่างสรุปโดยใช้sed
วิธีการจากคำตอบนี้ :
$ 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
มีอักขระพิเศษใด ๆ ที่น่าสนใจเหมือนสแลช
prefix_lines \*
สำหรับคนที่ใช้ระบบ BSD / OSX มียูทิลิตี้ที่เรียกว่าlam
สั้นสำหรับลามิเนต lam -s prefix file
จะทำในสิ่งที่คุณต้องการ ฉันใช้มันในท่อเช่น:
find -type f -exec lam -s "{}: " "{}" \; | fzf
... ซึ่งจะค้นหาไฟล์ทั้งหมด, exec lam ในแต่ละไฟล์, ให้แต่ละไฟล์นำหน้าชื่อไฟล์ของตัวเอง (และปั๊มผลลัพธ์ไปยัง fzf สำหรับการค้นหา)
sed
งานเบา ๆ เช่นนี้ หากรู้ว่า "คำนำหน้า" เป็นเรื่องง่ายมากในการเลือกอักขระที่ไม่ได้มาจาก "คำนำหน้า"