কোনও পাঠ্য ফাইলে একটি সম্পূর্ণ লাইন লাইন নম্বর দ্বারা কীভাবে প্রতিস্থাপন করবেন


152

আমার একটি পরিস্থিতি আছে যেখানে আমি কোনও ফাইলের পুরো লাইনটি প্রতিস্থাপন করতে বাশ স্ক্রিপ্ট চাই। লাইন নম্বর সর্বদা একই থাকে, যাতে এটি একটি হার্ড-কোডেড ভেরিয়েবল হতে পারে।

আমি সেই লাইনে কিছু উপ-স্ট্রিং প্রতিস্থাপন করার চেষ্টা করছি না, আমি কেবলমাত্র একটি লাইনটি সম্পূর্ণ নতুন লাইনের সাথে প্রতিস্থাপন করতে চাই।

এটি করার জন্য কোনও বাশ পদ্ধতি আছে (বা একটি সহজ কিছু যা .sh স্ক্রিপ্টে ফেলে দেওয়া যেতে পারে)।

উত্তর:


228

সর্বাধিক নয়, তবে এটি কাজ করা উচিত:

sed -i 'Ns/.*/replacement-line/' file.txt

যেখানে Nআপনার লক্ষ্য লাইন নম্বর দ্বারা প্রতিস্থাপন করা উচিত। এটি মূল ফাইলটিতে লাইনটি প্রতিস্থাপন করে। পরিবর্তিত পাঠ্যটিকে অন্য কোনও ফাইলে সংরক্ষণ করতে, -iবিকল্পটি ড্রপ করুন :

sed 'Ns/.*/replacement-line/' file.txt > new_file.txt

1
স্ক্রিনে ডাম্প না করে প্রশ্নটিতে ফাইলকে সংশোধন করার কোনও উপায় আছে?
ব্যবহারকারী 788171

8
আমার জন্য তা বলে: sed: -e expression #1, char 26: unknown option to ``s'আমার লাইন হল: sed -i '7s/.*/<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpoint/</param-value>/' $TCE_SVN_HOME\trunk\tce\EWC\WebContent\WEB-INF\web.xml। কোন ধারণা?
দানিজেল

4
/প্রতিস্থাপন পাঠ্যের প্রতিটি sকমান্ডের সমাপ্তি স্ল্যাশ হিসাবে ব্যাখ্যা করা হবে যদি না অবতরণ হয় ( \/)। তবে সবচেয়ে সহজ কাজটি হ'ল ডিলিমিটার হিসাবে একটি ভিন্ন, অব্যবহৃত চরিত্র বেছে নেওয়া। উদাহরণস্বরূপ sed -i '7s{.*}{<param-value>http://...}' $TCE_SVN_HOME/trunk...,।
চ্যানার

4
এই ব্যাখ্যাটি কিছুটা বিভ্রান্তিকর এবং এটি কার্যকর বলে মনে হচ্ছে না। আপনার ছেলেরা যদি সেড এবং এর সীমানা নির্ধারণের ক্ষমতা নিয়ে সমস্যা থাকে তবে আপনি এটি একবার দেখতে চান: grymoire.com/Unix/Sed.html#uh-2 এটি বলে sযে সীমানা নির্ধারণের পিছনে প্রথম চরিত্রটি । সুতরাং আপনার কমান্ডটি ব্যবহার করতে উদাহরণস্বরূপ #এটির মতো এটি ব্যবহার করতে হবে:sed -i '7s#.*#<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpo‌​int/</param-value>#'
func0der

7
@ মেওনল'গুলিকে প্রসারিত করতে, ম্যাকওএসের -eযদি -iদেওয়া হয় তবে তা প্রয়োজন ; সুতরাং, সঠিক কমান্ডটি হয়ে যায়:sed -e 'Ns/.*/replacement-line/' -i '' file.txt
এলিওটিটিসিবিএল

44

আমি আসলে এই স্ক্রিপ্টটি কিছুক্ষণ আগে আমাদের সংস্থার ইউএনআইএক্স সার্ভারে ক্রোন ফাইলে কোডের একটি লাইন প্রতিস্থাপন করতে ব্যবহার করেছি। আমরা এটিকে সাধারণ শেল স্ক্রিপ্ট হিসাবে কার্যকর করেছি এবং কোনও সমস্যা নেই:

#Create temporary file with new line in place
cat /dir/file | sed -e "s/the_original_line/the_new_line/" > /dir/temp_file
#Copy the new file over the original file
mv /dir/temp_file /dir/file

এটি লাইন নম্বর দ্বারা যায় না, তবে আপনি খুব সহজেই একটি লাইনের নম্বর ভিত্তিক সিস্টেমে স্যুইচ করতে পারেন লাইনের নম্বরটি আগে s/রেখে এবং তার জায়গায় একটি ওয়াইল্ডকার্ড রেখে the_original_line


17
বিড়ালের sed -e "s/.../.../" /dir/file > /dir/temp_file
অকেজো

24
দোভাষা / সংকলক হয়ত বোধহয়, তবে এটি পড়ার জন্য নয়। @ কাইলের কোডটি দুর্দান্তভাবে বাম থেকে ডানদিকে পড়ে; আপনি যে আইডেমটি আইএমও ব্যবহার করেছেন সেটি ক্রিয়াপদটি বিশেষ্যটির আগে রয়েছে বলে নয়।
ক্লেটন স্ট্যানলি

1
এই দুটি লাইন একীভূত করার জন্য কি কোনও উপায় আছে যেমন উদাহরণস্বরূপsed -e "s/.../.../" /dir/file > /dir/file
পাবুডু দোডাঙ্গোদা

22

ধরা যাক আপনি "আলাদা" পাঠ্যের সাথে লাইন 4 প্রতিস্থাপন করতে চান। আপনি AWK এর মতো ব্যবহার করতে পারেন:

awk '{ if (NR == 4) print "different"; else print $0}' input_file.txt > output_file.txt

এডাব্লুকে ইনপুটটিকে "রেকর্ডগুলি" "ক্ষেত্রগুলিতে" বিভক্ত বলে বিবেচনা করে। ডিফল্টরূপে, একটি লাইন একটি রেকর্ড। NRদেখা রেকর্ড সংখ্যা। $0বর্তমান সম্পূর্ণ রেকর্ড উপস্থাপন করে (যদিও রেকর্ড $1থেকে প্রথম ক্ষেত্র এবং আরও অনেক কিছু; ডিফল্টরূপে ক্ষেত্রগুলি লাইন থেকে শব্দ)।

সুতরাং, যদি বর্তমান লাইন সংখ্যা 4 হয় তবে স্ট্রিংটি "আলাদা" মুদ্রণ করুন তবে অন্যথায় লাইনটি অপরিবর্তিতভাবে মুদ্রণ করুন।

এডাব্লুকে- { }তে, প্রতিটি ইনপুট রেকর্ডে প্রোগ্রাম কোডটি একবারে রানের সাথে সংযুক্ত থাকে।

শেলের মতো জিনিসগুলির ব্যাখ্যা করার চেষ্টা থেকে শেলকে আটকে রাখতে আপনাকে একক-উক্তিগুলিতে AWK প্রোগ্রামটি উদ্ধৃত করতে হবে $0

সম্পাদনা: নীচের মন্তব্যে @ চেপনার থেকে একটি খাটো এবং আরও মার্জিত AWK প্রোগ্রাম:

awk 'NR==4 {$0="different"} { print }' input_file.txt

কেবল রেকর্ডের জন্য (অর্থাত্ লাইন) 4 নম্বর, পুরো রেকর্ডটি "ভিন্ন" স্ট্রিংয়ের সাথে প্রতিস্থাপন করুন। তারপরে প্রতিটি ইনপুট রেকর্ডের জন্য, রেকর্ডটি মুদ্রণ করুন।

স্পষ্টতই আমার AWK দক্ষতা মরিচা! ধন্যবাদ, চ্যাপনার

সম্পাদনা করুন: এবং ডেনিস উইলিয়ামসনের একটি আরও ছোট সংস্করণ দেখুন:

awk 'NR==4 {$0="different"} 1' input_file.txt

এটি কীভাবে মন্তব্যে ব্যাখ্যা করা হয়: 1সর্বদা সত্যের মূল্যায়ন করে, তাই সম্পর্কিত কোড ব্লক সর্বদা চলমান। তবে কোনও সম্পর্কিত কোড ব্লক নেই, যার অর্থ AWK কেবল পুরো লাইনটি মুদ্রণের জন্য এটির ডিফল্ট ক্রিয়া করে। এডাব্লুকে এই জাতীয় সংক্রমণের প্রোগ্রামগুলির জন্য ডিজাইন করা হয়েছে।


3
একটু খাটো: awk 'NR==4 {$0="different"} { print }' input_file.txt
চিপনার

2
@ চেপার: একটু খাটো:awk 'NR==4 {$0="different"}1' input_file.txt
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত

@ ডেনিস উইলিয়ামসন, আমি জানি না কীভাবে এটি কাজ করে! এই পিছনেটি কী করে 1? (দ্রষ্টব্য: আমি এটি পরীক্ষা করেছি এবং এটি সত্যিই কাজ করে! আমি কীভাবে তা বুঝতে পারি না))
স্টিভেহা

1
আমি অনুভব করেছি যে শর্তহীন মুদ্রণের সংক্ষিপ্তসার করার উপায় আছে! @ স্টেভাhaা: 1 টি হ'ল একটি সত্যিকারের মান, যার অর্থ একটি "প্যাটার্ন" যা সর্বদা মেলে। এবং কোনও ম্যাচের জন্য ডিফল্ট ক্রিয়া হ'ল বর্তমান লাইনটি মুদ্রণ করা।
চিপনার

19

এই পরীক্ষার ফাইল দেওয়া হয়েছে (test.txt)

Lorem ipsum dolor sit amet,
consectetur adipiscing elit. 
Duis eu diam non tortor laoreet 
bibendum vitae et tellus.

নিম্নলিখিত কমান্ডটি প্রথম পংক্তিকে "নিউলাইন পাঠ্যে" প্রতিস্থাপন করবে

$ sed '1 c\
> newline text' test.txt

ফলাফল:

newline text
consectetur adipiscing elit. 
Duis eu diam non tortor laoreet 
bibendum vitae et tellus.

আরো তথ্য পাওয়া যাবে এখানে

http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/


2
এটি সঠিক উত্তর হওয়া উচিত। সি পতাকাটি যা প্রয়োজন ঠিক তা করে (প্রদত্ত পাঠ্যের সাথে একটি সংখ্যাযুক্ত রেখা প্রতিস্থাপন করে)।
অ্যাডেলফাস

সেডের সাথে বিকল্প সিনট্যাক্স যা স্টডআউটে ফাইলটির প্রতিধ্বনি দেয় না: stackoverflow.com/a/13438118/4669135
গ্যাব্রিয়েল ডেভিলার্স

এটি সঠিক উত্তর, তবে কেন কুৎসিত লাইন ব্রেক? sed '1 cnewline text' test.txtপাশাপাশি এটি করতে হবে।
দেব-নাল

7

বাশ-এ, N, M কে লাইন সংখ্যা দ্বারা এবং xxx yY- কে আপনি চান তা প্রতিস্থাপন করুন

i=1
while read line;do
  if((i==N));then
    echo 'xxx'
  elif((i==M));then
    echo 'yyy'
  else
    echo "$line"
  fi
  ((i++))
done  < orig-file > new-file

সম্পাদনা

আসলে এই সমাধানটিতে "solution 0" "\ t" এবং "\" অক্ষরগুলির সাথে কিছু সমস্যা রয়েছে

"\ t", পড়ার আগে আইএফএস = রেখে সমাধান করা যেতে পারে: "\", -r এর সাথে লাইনের শেষে

IFS= read -r line

তবে "\ 0" এর জন্য ভেরিয়েবলটি কেটে ফেলা হয়েছে, খাঁটি বাশের কোনও সমাধান নেই: ন্যাশ-অক্ষর (\ 0) যুক্ত স্ট্রিংটি বসের মধ্যে একটি ভেরিয়েবলের জন্য নির্ধারণ করুন তবে সাধারণ পাঠ্য ফাইলে কোনও নুল অক্ষর নেই \ 0

পার্ল একটি ভাল পছন্দ হবে

perl -ne 'if($.==N){print"xxx\n"}elsif($.==M){print"yyy\n"}else{print}' < orig-file > new-file

আমি খাঁটি BASH সমাধানের চেষ্টা করার কথা ভাবিও নি!
স্টিভেহা

4
# Replace the line of the given line number with the given replacement in the given file.
function replace-line-in-file() {
    local file="$1"
    local line_num="$2"
    local replacement="$3"

    # Escape backslash, forward slash and ampersand for use as a sed replacement.
    replacement_escaped=$( echo "$replacement" | sed -e 's/[\/&]/\\&/g' )

    sed -i "${line_num}s/.*/$replacement_escaped/" "$file"
}

3

চেপনারের দুর্দান্ত উত্তর এটি বাশ শেলের জন্য আমার জন্য কাজ করছে।

 # To update/replace the new line string value with the exiting line of the file
 MyFile=/tmp/ps_checkdb.flag

 `sed -i "${index}s/.*/${newLine}/" $MyFile`

এখানে
index- লাইন নং
newLine- নতুন লাইন স্ট্রিং যা আমরা প্রতিস্থাপন করতে চাই।


একইভাবে নীচের কোডটি ফাইলের একটি নির্দিষ্ট লাইন পড়তে ব্যবহৃত হয়। এটি প্রকৃত ফাইলকে প্রভাবিত করবে না।

LineString=`sed "$index!d" $MyFile` 

এখানে
!d- লাইন নং ব্যতীত অন্যান্য রেখাগুলি মুছে ফেলবে $index সুতরাং আমরা $indexফাইলটিতে নং এর লাইনের স্ট্রিং হিসাবে আউটপুট পাব ।


তবে এটি আমার বাশ কেন কেবল ফলাফল দেখায় ${newline}?
সিকিসিস

1

ম্যাক আমি ব্যবহার করেছি

sed -i '' -e 's/text-on-line-to-be-changed.*/text-to-replace-the=whole-line/' file-name

-2

আপনি সেড কমান্ডে প্যারামিটারগুলিও পাস করতে পারেন:

test.sh

#!/bin/bash
echo "-> start"
for i in $(seq 5); do
  # passing parameters to sed
  j=$(($i+3))
  sed -i "${j}s/.*/replaced by '$i'!/" output.dat
done
echo "-> finished"
exit 

অরিঞ্জিয়াল আউটপুট.ড্যাট:

a
b
c
d
e
f
g
h
i
j

নির্বাহ ./test.sh নতুন output.dat দেয়

a
b
c
replaced by '1'!
replaced by '2'!
replaced by '3'!
replaced by '4'!
replaced by '5'!
i
j

1
এই উদাহরণটির জন্য আপনার কেন একটি লুপের প্রয়োজন হয়, কেবল সমাধানটি অবিচ্ছিন্ন করে দেয়? line=5; sed -i "${line}s/.*/replaced by '$i'!/" output.dat
রব

আপনার
এটির
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.