प्रत्येक पंक्ति की शुरुआत में एक उपसर्ग स्ट्रिंग जोड़ें


334

मेरे पास नीचे के रूप में एक फाइल है:

line1
line2
line3

और मैं पाना चाहता हूं:

prefixline1
prefixline2
prefixline3

मैं एक रूबी स्क्रिप्ट लिख सकता था, लेकिन अगर मुझे ज़रूरत नहीं है तो बेहतर है।

prefixशामिल होंगे /। यह एक रास्ता है, /opt/workdir/उदाहरण के लिए।

जवाबों:


526
# 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/'

1
@बेनजामिन, मैंने पहले ही आपके उत्तर को रद्द कर दिया था, हालांकि, मैं sedइस तरह के हल्के कार्यों के लिए पसंद करता हूं । यदि "उपसर्ग" ज्ञात है, तो "उपसर्ग" से नहीं चरित्र को चुनना बहुत आसान है।
आलोक सिंघल

1
मत भूलना तुम भी sedएक पाइप लाइन में उपयोग कर सकते हैं , जैसे foo | sed -e 's/^/x /' | bar
जिग

1
@ डाटामन कूल। एक और तरीका होगा sed -e '2,$s/^/prefix/'
आलोक सिंघल

1
@BinChen बचने /की तरह \/(एकल उद्धृत तार में) या \\/(डबल-कोटेड तार में)

8
sed -e 's/$/postfix/' fileयदि आप प्रत्येक पंक्ति के अंत में स्ट्रिंग जोड़ना चाहते हैं, तो उपयोग करें ।
ब्रायन

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

पर्ल (स्थान प्रतिस्थापन में) के साथ:

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

8
एक पाइप / स्ट्रीम या चर के साथ:prtinf "$VARIABLE\n" | awk '$0="prefix"$0'
ThorSummoner

2
एक बड़ी फ़ाइल (12 G) के साथ, awkरिपोर्ट करता है awk: out of memory in readrec 1 source line number 1, लेकिन समाधान sedसफलतापूर्वक पूरा होता है।
16

33

आप पूर्व मोड में विम का उपयोग कर सकते हैं:

ex -sc '%s/^/prefix/|x' file
  1. % सभी लाइनों का चयन करें

  2. s बदलने के

  3. x सहेजें और बंद करें


1
मेरे लिए, मैं सिर्फ फ़ाइल को vim और type में खोलता हूँ :%s/^/prefix/, क्योंकि यह रणनीति कई स्थितियों में उपयोगी साबित होती है
फ्रैंक ब्राइस

23

यदि आपका उपसर्ग थोड़ा जटिल है, तो बस इसे एक चर में रखें:

prefix=path/to/file/

उसके बाद, आप उस चर को पास करते हैं और उसके साथ अजीब व्यवहार करते हैं:

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


6

शेल का उपयोग करना:

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

5

यहाँ अधिक हाईटाइल tsसे कमांड का उपयोग करते हुए एक उच्च पठनीय ऑनलाइनर समाधान है

$ 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

कई लिनक्स डिस्ट्रोस पर डिफ़ॉल्ट रूप से 'ts' स्थापित नहीं है। इसके अलावा, डाउनवोटिंग क्योंकि इस उत्तर में अनुगामी "tr -d" "लाइनों से सभी रिक्त स्थान को हटा देगा, न कि केवल 'ts' द्वारा जोड़ा गया स्थान
टिम बर्ड

3

जबकि मुझे नहीं लगता कि पियर की यह चिंता थी, मुझे एक ऐसे समाधान की आवश्यकता थी जो किसी फ़ाइल के लाइव "टेल" से आउटपुट में देरी न करे, क्योंकि मैं एक साथ कई अलर्ट लॉग की निगरानी करना चाहता था, प्रत्येक लाइन को उसके संबंधित लॉग के नाम के साथ प्रीफ़िक्स करना ।

दुर्भाग्य से, सीड, कट, आदि ने बहुत अधिक बफरिंग शुरू की और मुझे सबसे वर्तमान लाइनों को देखने से रोक दिया। स्टीवन पेनी के -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}

1
-uबफरिंग से बचने के लिए सेड के विकल्प का उपयोग करें ।
ब्रायन लार्सन

2
बफरिंग को अनबफर / स्टडब्यूफ के साथ बंद किया जा सकता है, देखें unix.stackexchange.com/q/25372/6205
myroslav

2

एड का उपयोग करना:

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

यह विकल्प, प्रत्येक पंक्ति ( ,), रेखा की शुरुआत ( ^) के साथ है prefixwqबचाता है और बाहर निकलता है।

यदि प्रतिस्थापन स्ट्रिंग में एक स्लैश है, तो हम इसके लिए एक भिन्न सीमांकक का उपयोग कर सकते हैं s:

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

मैंने EOEपैरामीटर विस्तार को रोकने के लिए यहां-डॉक्टर डेलिमिटर ("एड का अंत") उद्धृत किया है । इस उदाहरण में, यह निर्विवाद रूप से भी काम करेगा, लेकिन आश्चर्य से बचने के लिए यह अच्छा अभ्यास है यदि आपके पास कभी भी $आपकी एड स्क्रिप्ट है।


2

(& पैटर्न द्वारा मिलान किए गए इनपुट का पूरा भाग) का उपयोग करना:

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

या वापस संदर्भ का उपयोग कर:

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

2
  1. आप बैकरेक्शन तकनीक का उपयोग करके भी इसे प्राप्त कर सकते हैं

    sed -i.bak 's/\(.*\)/prefix\1/' foo.txt
    
  2. आप इस तरह से awk के साथ भी उपयोग कर सकते हैं

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

1

इस उत्तरsed से दृष्टिकोण का उपयोग कर एक लिपटा हुआ उदाहरण दिया गया है :

$ 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
यदि PREFIXस्लैश की तरह किसी भी वर्ण विशेष को sed करने के लिए यह काम नहीं करेगा ।
जोश

अच्छी बात है ... यदि आप पाते हैं कि आप स्लैश अलॉट का उपयोग करते हैं, तो आप अलग-अलग सीमांकक को सीड पार्ट के साथ उपयोग कर सकते हैं, जैसा कि यहाँ विस्तृत है , जो आपको खोजों में इसका उपयोग करने की अनुमति देगा। अन्य विशेष सेड चर को स्लैश के साथ भागकर अंदर रखा जा सकता है, जैसेprefix_lines \*
ब्रैड पार्क्स

0

बीएसडी / ओएसएक्स सिस्टम पर लोगों के लिए उपयोगिता कहा जाता है lam, जो टुकड़े टुकड़े के लिए छोटा है। lam -s prefix fileजो चाहोगे, करोगे। मैं इसे पाइपलाइनों में उपयोग करता हूं, उदाहरण के लिए:

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

... जो सभी फाइलें मिलेंगी, उनमें से प्रत्येक पर लैम निष्पादित करें, प्रत्येक फाइल को अपने स्वयं के फ़ाइल नाम का एक उपसर्ग दें। (और खोज के लिए fzf के लिए आउटपुट पंप)


आप सही हैं, ऐसा प्रतीत होता है कि यह एक बीएसडी केवल कमांड है। POSIX ने इसे पेस्ट से बदल दिया, लेकिन पेस्ट में पूर्ण विभाजक स्ट्रिंग जोड़ने की सुविधा नहीं है। मैं अपना जवाब अपडेट करूंगा।
रे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.