ฉันมีไฟล์ดังนี้:
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งานเบา ๆ เช่นนี้ หากรู้ว่า "คำนำหน้า" เป็นเรื่องง่ายมากในการเลือกอักขระที่ไม่ได้มาจาก "คำนำหน้า"