Vi ফাইলের শেষে নিঃশব্দে একটি নতুন লাইন (এলএফ) যুক্ত করে?


36

আমি একটি অদ্ভুত আচরণ বুঝতে কষ্ট: (: এলএফ যেমন একটি ইউনিক্স (হয় হওয়া ASCII ষষ্ঠ একটি newline যোগ করার জন্য মনে হয় , AIX ) সিস্টেম) ফাইলের শেষে যখন আমি বিশেষভাবে তা না টাইপ হয়নি করেন।

আমি vi তে ফাইলটি সম্পাদনা করি (শেষের দিকে একটি নতুন লাইন ইনপুট না দেওয়ার বিষয়ে যত্ন নিচ্ছি):

# vi foo   ## Which I will finish on the char "9" and not input a last newline, then `:wq`
123456789
123456789
123456789
123456789
~
~
  ## When I save, the cursor is just above the last "9", and no newline was added.

আমি vi আশা করি এটি "যেমন আছে" সংরক্ষণ করুন, সুতরাং 39 বাইট থাকবে: প্রথম তিনটি লাইনের প্রত্যেকটিতে 10 টি ASCII অক্ষর (1 থেকে 9 নম্বর, পরে একটি নতুন লাইন (আমার সিস্টেমে এলএফ)) থাকবে এবং শেষটিতে কেবল 9 লাইন (1 থেকে 9 টি অক্ষর, কোনও নতুন লাইন / এলএফ শেষ হবে না)।

তবে এটি সংরক্ষণ করা হয় যখন আমি এটি সংরক্ষণ করি এটি 40 বাইট (39 এর পরিবর্তে), এবং ওড একটি সমাপ্ত এলএফ দেখায় :

# wc foo
       4       4      40 foo  ## I expected 39 here! as I didn't add the last newline
# od -a toto
0000000    1   2   3   4   5   6   7   8   9  lf   1   2   3   4   5   6
0000020    7   8   9  lf   1   2   3   4   5   6   7   8   9  lf   1   2
0000040    3   4   5   6   7   8   9  lf
0000050
     ## An "lf" terminates the file?? Did vi add it silently?

আমি যদি ভিআই এর ভিতরে যা করেছি ঠিক তেমন কাজ করে যদি ফাইলটি তৈরি করি তবে এটি প্রত্যাশার মতো কাজ করে:

# ## I create a file with NO newline at the end:
# printf "123456789\n123456789\n123456789\n123456789" > foo2
# wc foo2  ## This one is as expected: 39 bytes, exactly as I was trying to do above with vi.
       3       4      39 foo  ## As expected, as I didn't add the last newline

  ## Note that for wc, there are only three lines!
  ## (So wc -l doesn't count lines; it counts the [newline] chars... Which is rather odd.)

# root@SPU0WMY1:~  ## od -a foo2
0000000    1   2   3   4   5   6   7   8   9  lf   1   2   3   4   5   6
0000020    7   8   9  lf   1   2   3   4   5   6   7   8   9  lf   1   2
0000040    3   4   5   6   7   8   9
0000047                                ## As expected, no added LF.

আমি যদি vi দিয়ে আবার খুলি তবে উভয় ফাইল (foo (40 অক্ষর) এবং foo2 (39 টি অক্ষর) হুবহু একই প্রদর্শিত হবে ...

এবং আমি যদি vi এর মধ্যে foo2 (39 টি অক্ষর, কোনও নতুন লাইনের অবসান নেই) ও এটি সম্পাদনা না :wqকরেই করি তবে এটি 40 অক্ষর লিখেছে এবং লাইনফিডটি উপস্থিত হবে!

আমার কাছে আরও সাম্প্রতিক vi (অ্যাক্সেস অ্যাক্সেস) থাকতে পারে না (আমি এটি এআইএক্স, vi ( ভিম নয় ) সংস্করণে 3.10 মনে করি? (কোনও "রূপান্তর" বা এটি জানার অন্যান্য উপায় নেই))।

# strings /usr/bin/vi | grep -i 'version.*[0-9]'
@(#) Version 3.10

ভিআই (এবং সম্ভবত সাম্প্রতিক সংস্করণে নেই? বা ভিম?) এর জন্য ফাইলের শেষে নিঃশব্দে একটি নতুন লাইন যুক্ত করা কি স্বাভাবিক? (আমি ভেবেছিলাম ~ ইঙ্গিত করেছে যে আগের লাইনটি কোনও নতুন লাইনের সাথে শেষ হয়নি NOT)

-

সম্পাদনা করুন: নীচের উত্তরের জন্য একটি বৃহত ধন্যবাদ সহ কিছু অতিরিক্ত আপডেট এবং কিছু সংক্ষিপ্তসার:

  • vi নিঃশব্দে এই মুহুর্তে এটি একটি ফাইল লেখায় যা এর অভাবের সাথে একটি লেখনী নিউলাইন যুক্ত করে (ফাইলটি খালি না থাকলে)।

  • এটি কেবল লেখার সময় করে! (যেমন, আপনি: ডাব্লু পর্যন্ত, আপনি ব্যবহার করতে পারেন: e ফাইলটি খোলার সাথে সাথে এখনও রয়েছে কিনা তা যাচাই করতে ... (যেমন: এটি এখনও "ফাইলের নাম" দেখায় [শেষ লাইনটি সম্পূর্ণ নয়] এন লাইন, এম অক্ষর)। আপনি যখন সংরক্ষণ করেন, সুনির্দিষ্ট সতর্কতা ছাড়াই একটি নতুন লাইন চুপচাপ যুক্ত করা হয় (এটি কতটা বাইট সংরক্ষণ করে তা বলে না, তবে এটি বেশিরভাগ ক্ষেত্রেই একটি নতুন লাইন যুক্ত হয়েছিল তা জানা যথেষ্ট নয়) (জিলিয়াগ্র্রে আমার সাথে কথা বলার জন্য ধন্যবাদ vi বার্তা খোলার ফলে, পরিবর্তনটি আসলে কখন ঘটে তা জানার উপায় খুঁজতে আমাকে সহায়তা করেছিল)

  • এটি (নীরব সংশোধন) হ'ল পসিক্স আচরণ! (রেফারেন্সের জন্য @ খালি পায়ে-আইও উত্তর দেখুন)


কেবল সম্পূর্ণতার জন্য, এআইএক্সের কোন সংস্করণ (সম্পূর্ণ সংস্করণ)।
এইটবিটনি

2
আমি এআইএক্স এর vi এর এই বিকল্পটি রাখার বিষয়ে অবগত নই - কেবলমাত্র
জেফ শ্যাচলার

1
@ জেফ শ্যাচলার: লিঙ্কটির জন্য THX। দুর্ভাগ্যক্রমে দেশীয় vi এর ":: সেট নোওল" বা বাইনারি মোডে খোলার জন্য -b বিকল্পও নেই ...
অলিভিয়ার ডুলাক

1
কমান্ডটি viচালিয়ে আপনি সংস্করণ বা কমপক্ষে তার উত্স সম্পর্কে কোনও ধারণা পেতে সক্ষম হবেন :ve
jlliagre

1
পছন্দ করুন কোনও কারণে আইবিএম exম্যানুয়াল পৃষ্ঠাটি সরিয়ে ফেলল যেখানে :verকমান্ডটি সাধারণত নথিভুক্ত থাকে।
jlliagre

উত্তর:


28

এটি প্রত্যাশিত viআচরণ।

আপনার ফাইলে একটি অসম্পূর্ণ শেষ লাইন রয়েছে তাই কঠোরভাবে কথা বলা (অর্থাত্ পসিক্স স্ট্যান্ডার্ড অনুযায়ী), এটি কোনও পাঠ্য ফাইল নয় বাইনারি ফাইল।

vi যা কোনও পাঠ্য ফাইল সম্পাদক, বাইনারি নয়, আপনি যখন সংরক্ষণ করেন তখন কৌতূহলবশত এটিকে ঠিক করে দেয়।

এই মত অন্যান্য টেক্সট ফাইল টুলস পারবেন wc, sedআশা আউটপুট প্রদান লেগেছে। নোট যে viবিষয়টি নিয়ে নীরব নয়:


$ printf "one\ntwo" >file     # Create a unterminated file
$ cat file                    # Note the missing newline before the prompt
one
two$ wc -l file               # wc ignores the incomplete last line
       1 file
$ sed '' file > file1
$ cat file1                   # so does a legacy sed
one
$ PATH=$(getconf PATH) sed  '' file
one                           # while a POSIX conformant sed warns you:
sed: Missing newline at end of file file.
two
$ vi file
one
two
~
~
~                             # vi tells you too about the issue
"file" [Incomplete last line] 2 lines, 7 characters

:w

"file" 2 lines, 8 characters  # and tells it writes two lines
                              # You'll even notice it writes one more
                              # character if you are a very shrewd observer :-)
:q
$ cat file                    # the file is now valid text
one
two
$ wc -l file                  # wc reports the expected number of lines
       2 file
$ sed '' file > file1         # sed works as expected
$ cat file1
one
two

দ্রষ্টব্য, আপনি কোন viসংস্করণটি চালাচ্ছেন সে সম্পর্কে কিছু সূত্র পেতে , আপনি :veকমান্ডটি ব্যবহার করতে পারেন । এটি এখানে দেখায় আমি এখানে একটি উত্তরাধিকারী এসভিআর 4 ব্যবহার করি, অবশ্যই না vim:

:ve
Version SVR4.0, Solaris 2.5.0

স্পষ্টতই, আপনার বক্তব্য:

:ve
Version 3.10

সম্ভবত এর অর্থ viএআইএক্স এসভিআর 3 উত্স কোডের উপর ভিত্তি করে।

যাইহোক, এই আচরণ, এবং [Incomplete last line]সতর্কতা বার্তাটি viকমপক্ষে 1979 এবং এএএএআইপি-র পরম্পরা বিল জয়ের উত্স কোডে রয়েছে, সিস্টেম ভি উত্স কোড রিলিজ থেকে তৈরি সমস্ত শাখায় ধরে রাখা হয়েছে, যা থেকে এআইএক্সের মতো মালিকানাধীন ইউনিক্স নির্মিত হয়েছিল।

কালানুক্রমিকভাবে বলতে গেলে, এই আচরণটি তখন পসিক্স কনফারেন্সের পরিণতি নয় বরং বিল জয়ের মূল সিদ্ধান্তের ফলস্বরূপ যা ব্যবহারকারীরা বোগাসের পাঠ্য ফাইল সম্পাদনা করতে সহায়তা করে এবং তারপরে, এক দশক পরে, এই সহনশীলতা বজায় রাখার জন্য পসিক্স কমিটির সিদ্ধান্ত।

আপনি যদি এর edপরিবর্তে ব্যবহার করেন তবে আপনি viখেয়াল করবেন যে প্রাক্তনটি সমস্যাটি সম্পর্কে আরও ভারবস, কমপক্ষে যদি আপনার edএসভিআর 3 বা নতুন উত্স শাখা থেকে থাকে:

$ ed file
'\n' appended
8
q

আরও মনে রাখবেন যে একটি খালি ফাইল হ'ল একটি বৈধ পাঠ্য ফাইল যা শূন্য লাইন ধারণ করে। যেহেতু ঠিক করার জন্য কোনও নির্ধারিত লাইন viনেই, ফাইলটি সংরক্ষণ করার সময় কোনও নতুন লাইন যুক্ত করা হয় না।


1
আমি বিশ্বাস করি আপনি vi এর জন্য vim ভুল করেছেন;) উত্তরাধিকার vi এর চেয়ে খুব কম ভার্বোস ...
অলিভিয়ার ডুলাক

@ অলিভিয়ারডুলাক আমি তাদের গুলিয়ে ফেলছি না। এই পরীক্ষাটি ওপির viমতোই এসভিআর 4 লিগ্যাসি ব্যবহার করে করা হয়েছিল , যদিও ভিন্ন ইউনিক্সে। এটি vimবা অন্য কোনও ক্লোন নয়। এটি পরিষ্কার করতে উত্তর আপডেট হয়েছে।
jlliagre

অলিভিয়ারডুলাক হুম, আমি কেবল লক্ষ্য করেছি আপনি আসলে ওপি are দেখে মনে হচ্ছে এআইএক্স এর viবাস্তবায়নের জন্য একটি পুরানো সিস্টেম ভি শাখা ব্যবহার করছে । সম্ভবত এসভিআর 3। আপনি [Incomplete last line]যখন ফাইলটি খুলবেন তখন কি নিশ্চিত যে কোনও বার্তা নেই ?
jlliagre

@ অলিভিয়ারডুলাক এই লিঙ্কটি বোঝায় যে এটি খুব একই বার্তাটি এআইএক্সvi বাস্তবায়নের দ্বারা প্রদর্শিত হতে পারে : www-01.ibm.com/support/docview.wss?uid=isg1IZ27694
jlliagre

আমি আগামীকাল এটি দেখার চেষ্টা করব
অলিভিয়ার ডুলাক

51

পসিক্সের এই আচরণ প্রয়োজন, সুতরাং এটি কোনওভাবেই অস্বাভাবিক নয়।

থেকে POSIX ম্যানুয়াল vi :

ফাইলগুলি ইনপুট করুন

ভি কমান্ড দ্বারা সমর্থিত ইনপুট ফাইলগুলির বিবরণের জন্য প্রাক্তন কমান্ডের ইনপুট ফাইলগুলি বিভাগটি দেখুন।

POSIX প্রাক্তন ম্যানুয়ালটিতে অনুসরণ করা :

ফাইলগুলি ইনপুট করুন

ইনপুট ফাইলগুলি হ'ল পাঠ্য ফাইল বা ফাইলগুলি যে কোনও অসম্পূর্ণ শেষ লাইনের except LINE_MAX} -1 বাইটের দৈর্ঘ্য নয় এবং এতে কোনও NUL অক্ষর নেই সেগুলি ব্যতীত পাঠ্য ফাইল হবে। ডিফল্টরূপে, যে কোনও অসম্পূর্ণ শেষ লাইনের সাথে চিকিত্সা করা হবে যেমন এটির পিছনের <নিউ নিউলাইন> রয়েছে। অন্যান্য রূপের ফাইলগুলির সম্পাদনা প্রাক্তন বাস্তবায়ন দ্বারা অনুমোদিত হতে পারে।

Vi ম্যানুয়ালটির OUTPUT ফাইল ফাইলটি প্রাক্তনকে পুনঃনির্দেশ করে:

আউটপুট ফাইল

প্রাক্তন থেকে আউটপুট হবে পাঠ্য ফাইল files

POSIX সংজ্ঞা একটি জোড়া:

3.397 পাঠ্য ফাইল

একটি ফাইল যা শূন্য বা আরও বেশি লাইনে বিভক্ত অক্ষর ধারণ করে। লাইনগুলিতে NUL টি অক্ষর থাকে না এবং <নিউলাইন> অক্ষর সহ কোনওরই দৈর্ঘ্যে {LINE_MAX} বাইট অতিক্রম করতে পারে না। যদিও POSIX.1-2-2008 পাঠ্য ফাইল এবং বাইনারি ফাইলগুলির মধ্যে পার্থক্য না করে (আইএসও সি স্ট্যান্ডার্ড দেখুন), অনেকগুলি ইউটিলিটি কেবল পাঠ্য ফাইলগুলিতে অপারেটিং করার সময় অনুমানযোগ্য বা অর্থপূর্ণ আউটপুট তৈরি করে। যে স্ট্যান্ডার্ড ইউটিলিটিগুলির মধ্যে এই জাতীয় বিধিনিষেধ রয়েছে তারা সর্বদা তাদের STDIN বা ইনপুট ফাইল বিভাগগুলিতে "পাঠ্য ফাইলগুলি" নির্দিষ্ট করে।

3.206 লাইন

শূন্য বা আরও অ-নিউ-লাইন> অক্ষর এবং একটি শেষ << নিউলাইন> চরিত্রের ক্রম।

এই ম্যানুয়াল পৃষ্ঠাগুলির অংশগুলির প্রসঙ্গে এই সংজ্ঞাটির অর্থ হ'ল যদি কোনও পূর্বসূরি / vi বাস্তবায়ন অবশ্যই কোনও ত্রুটিযুক্ত পাঠ্য ফাইলটি গ্রহণ করতে পারে যদি সেই ফাইলটির একমাত্র বিকৃতিটি অনুপস্থিত চূড়ান্ত নিউলাইন থাকে, যখন ফাইলটির বাফার লেখার ফলাফল অবশ্যই একটি বৈধ পাঠ্য ফাইল হতে হবে be

যদিও এই পোস্টটি পসিক্স স্ট্যান্ডার্ডের 2013 সংস্করণটিকে রেফারেন্স করেছে, প্রাসঙ্গিক শর্তগুলিও পুরানো 1997 এর সংস্করণে উপস্থিত হয়

সবশেষে, আপনি যদি প্রাক্তনটির নতুন লাইনে থাকা পেনশনটিকে অপ্রয়োজনীয় বলে মনে করেন তবে আপনি সপ্তম সংস্করণ ইউনিক্সের (1979) অসহিষ্ণু এড দ্বারা গভীরভাবে লঙ্ঘিত বোধ করবেন। ম্যানুয়াল থেকে :

কোনও ফাইল পড়ার সময়, এডকৃত শেষ নিউলাইনের পরে ASCII NUL টি অক্ষর এবং সমস্ত অক্ষর বাদ দেয়। এটি নন-এসসিআইআই অক্ষরযুক্ত ফাইলগুলি পড়তে অস্বীকার করে।


ধন্যবাদ, যে আমার প্রশ্নের উত্তর দেয়। আমি আরও কিছু দিন অপেক্ষা করব যদি আরও ভাল উত্তর কোলস আপ হয় তবে এখনই আমি অনুভব করছি আপনি গ্রহণযোগ্য উত্তর হতে পারেন।
অলিভিয়ার ডুলাক

পুরোপুরি নথিভুক্ত জবাবটি খুব ভালভাবে করা হয়েছে, সরাসরি চশমা থেকে! :)
ওয়াইল্ডকার্ড

1
@ উইল্ডকার্ড, আচরণটি চশমাগুলির আগে যদিও।
jlliagre

@ জেলিয়াগ্রে, যদি না আপনি বিল জয় বা সম্ভবত ex(তার নাম জানেন না) স্রষ্টার কোনও স্মৃতিচিহ্ন না পেয়ে থাকেন, তবে আমি মনে করি যে পসিক্স চশমা যতটা আশা করা যায় ঠিক তত ভাল। ;) এই মুহূর্তে "মূল উত্স" এর নিকটতম, যদিও এটি সত্য তবে তারা বিদ্যমান কার্যকারিতাটির কমবেশি বর্ণনা হিসাবে শুরু করেছিল।
ওয়াইল্ডকার্ড

3
@Wildcard exবিল জয় এবং চাক জগৎ এর সহযোগিতায় লেখা হয়েছিল ( web.cecs.pdx.edu/~kirkenda/joy84.html ।) আমি প্রশ্ন না POSIX চশমা এবং আসলে বর্তমান viরিলিজের এটি অনুসরণ না, আমি শুধু আচরণ রাষ্ট্র দীর্ঘ এটা পূর্বাভাস।
jlliagre

1

আমি অন্য কোনও আচরণের কথা মনে করতে পারি না যে কোনও ফাইলের শেষে একটি নতুন লাইন যুক্ত করা হয় ( vi80 এর দশকের মাঝামাঝি থেকে ব্যবহার করে )।

~ইঙ্গিত করে যে পর্দা যে পাঠ্য অংশ নয় একটি লাইন, না যে ফাইল একটি newline মধ্যে শেষ হয় না। (আপনি যদি ~শেল স্ক্রিপ্টগুলির সর্বশেষ লাইনে রেখে দেন তবে ত্রুটিগুলি সনাক্ত করতে অসুবিধা পেতে পারেন )। আপনি যদি শেষের দিকে একটি নতুন লাইনের সাথে একটি সংক্ষিপ্ত ফাইল লোড করেন তবে আপনি ~নিজেই দেখতে পাবেন এবং অস্বীকার করবেন যে আপনার ধারণা এটি নন-লাইন-শেষের পাঠ্যকে ইঙ্গিত করে।


আমাকে কী আশ্চর্য করে একটি নতুন লাইন যুক্ত করা ... আমি আশা করি vi এটিকে নিঃশব্দে যোগ করবেন না, তবে মনে হয় এটি ঘটে ... আমি এই মনোভাবের ব্যাখ্যা খুঁজছি (উদ্বেগজনক সত্য: আমি foo2 খুলি না) পিছনে এলএফ) এবং ঠিক: ডাব্লু ডাব্লু, এটি তার বিষয়বস্তু পরিবর্তন করে ... সুতরাং এটি আমাকে কিছু দেখায় তবে অন্য জিনিসটি সংরক্ষণ করে ... অদ্ভুত, কমপক্ষে বলতে গেলে ^^
অলিভিয়ার দুলাক

এর পূর্বসূরীতে ( ed) আপনি লাইন তৈরি এবং সেগুলি সম্পাদনা করতে পারবেন, অক্ষর যুক্ত করে নয়। আমি লাইন ওরিয়েন্টেড সম্পাদক হিসাবেও সবসময় ভিআই নিয়ে ভাবতাম। তবে আমি আপনার বিস্ময় বুঝতে পারি।
অ্যান্থন

1

শেল whileলুপের মাধ্যমে চূড়ান্তভাবে নতুন পংক্তিটি চালিত না হওয়া পাঠ্যটি চূড়ান্তভাবে শেষ লাইনে ফেলে দেওয়া হবে।

$ (echo transaction 1; echo -n transaction 2) \
  | while read line; do echo $line; done
transaction 1
$ 

একটি চূড়ান্ত নিউলাইন রয়েছে তা নিশ্চিত করা সঠিক এবং বুদ্ধিমান এবং যথাযথ ডিফল্ট। অন্য বিকল্পের মধ্যে চূড়ান্ত নিউলাইনের অভাবে পাঠ্য স্পর্শ করে এমন সমস্ত শেল কোড অডিট করার সময় জেনে রাখা এবং পাঠ্যটির শেষ লাইনটি হারাতে ঝুঁকিপূর্ণ অন্তর্ভুক্ত।

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