ব্যাকস্ল্যাশ অক্ষরের সাথে শেষ হওয়া সমস্ত লাইনকে আপনি কীভাবে একত্রিত করতে পারেন?


36

সেড বা অজকের মতো একটি সাধারণ কমান্ড লাইন সরঞ্জাম ব্যবহার করে, ব্যাকস্ল্যাশের মতো কোনও প্রদত্ত চরিত্রের সাথে শেষ হওয়া সমস্ত লাইনে যুক্ত হওয়া কি সম্ভব?

উদাহরণস্বরূপ, ফাইলটি দেওয়া:

foo bar \
bash \
baz
dude \
happy

আমি এই আউটপুট পেতে চাই:

foo bar bash baz
dude happy

1
এর মাধ্যমে ফাইলটি পাস করুন cpp:)
ইম্জ - ইভান জাখারিয়াচেভ

অনেক দুর্দান্ত উত্তর, আমি তাদের সমস্ত উত্তর হিসাবে চিহ্নিত করতে ইচ্ছুক! অ্যাজ, সিড এবং পার্লের দুর্দান্ত চেহারার জন্য ধন্যবাদ, এগুলি দুর্দান্ত উদাহরণ।
Cory Klein

উত্তর:


27

একটি সংক্ষিপ্ত এবং সহজ সেড সমাধান:

sed  '
: again
/\\$/ {
    N
    s/\\\n//
    t again
}
' textfile

বা জিএনইউ ব্যবহার করতে পারলে ওয়ান-লাইনার sed:

sed ':x; /\\$/ { N; s/\\\n//; tx }' textfile

1
ভাল ... আমি প্রাথমিকভাবে এটি তাকিয়েছিলাম এবং এটি বুঝতে পারি না (সুতরাং এটি খুব শক্ত ঝুড়ির মধ্যে enুকেনি) ... তবে গিলসের উত্তরটি গভীরভাবে দেখার পরে (যা বেশ কিছুটা সময় নিয়েছিল) আপনার উত্তরটির দিকে আমার আরও নজর ছিল এবং এটি উপলব্ধিযোগ্য বোধগম্য বলে মনে হয়েছিল আমি বুঝতে শুরু করেছি sed:) ... আপনি প্রতিটি লাইনটি সরাসরি প্যাটার্ন-স্পেসে সংযুক্ত করছেন, এবং যখন "স্বাভাবিকভাবে শেষ" রেখাটি আসে, তখন পুরো প্যাটার্নের স্পেস পড়ে এবং অটো প্রিন্টগুলি (কারণ কোনও বিকল্প নেই) ... ঝরঝরে! .. +1
পিটার.ও

@ ফ্রেড: ধন্যবাদ আমি মনে করি আমি সেডও বুঝতে শুরু করেছি, এটি মাল্টলাইন এডিটিংয়ের জন্য দুর্দান্ত সরঞ্জাম সরবরাহ করে তবে কীভাবে আপনার মিশ্রণটি পাবেন তা আপনার কী প্রয়োজন তা সোজা নয় এবং পঠনযোগ্যতা শীর্ষে নেই ...
নিউরিনো

ডস লাইন শেষ থেকে সাবধান, ওরফে। গাড়ি ফেরত নাকি \ আর!
ব্যবহারকারী 77376

1
কোনটি ভুলsed -e :a -e '/\\$/N; s/\\\n//; ta'
আইজাক

18

পার্ল দিয়ে এটি সম্ভবত সবচেয়ে সহজ (যেহেতু পার্ল সেড এবং অজকের মতো, আমি আশা করি এটি আপনার কাছে গ্রহণযোগ্য হবে):

perl -p -e 's/\\\n//'

সংক্ষিপ্ত এবং সহজ, আমি
এটিকে

17

এখানে একটি বিশ্রী সমাধান। যদি একটি লাইন একটি দিয়ে শেষ হয় \, ব্যাকস্ল্যাশটি ফালাটি মুছুন এবং কোনও লাইন শেষ না করেই শেষ করুন; অন্যথায় সমাপ্ত নিউলাইন দিয়ে লাইনটি মুদ্রণ করুন।

awk '{if (sub(/\\$/,"")) printf "%s", $0; else print $0}'

এটি সেডের ক্ষেত্রে খুব খারাপও নয়, যদিও বিশ্রী স্পষ্টতই বেশি পাঠযোগ্য।


2

এটি এর মতো কোনও উত্তর নয়। এটি সম্পর্কে একটি পার্শ্ব সমস্যা sed

বিশেষত, sedএটি বুঝতে আমার গিলসকে কমান্ড আলাদা করে টুকরো টুকরো করা দরকার ছিল ... আমি এটিতে কিছু নোট লিখতে শুরু করেছিলাম এবং তারপরে ভেবেছিলাম এটি কারওর পক্ষে কার্যকর হতে পারে ...

তাই এখানে এটা ... গিলেজ 'sed স্ক্রিপ্ট মধ্যে নথিভুক্ত বিন্যাস:


#!/bin/bash
#######################################
sed_dat="$HOME/ztest.dat"
while IFS= read -r line ;do echo "$line" ;done <<'END_DAT' >"$sed_dat"
foo bar \
bash \
baz
dude \
happy
yabba dabba 
doo
END_DAT

#######################################
sedexec="$HOME/ztest.sed"
while IFS= read -r line ;do echo "$line" ;done <<'END-SED' >"$sedexec"; \
sed  -nf "$sedexec" "$sed_dat"

  s/\\$//        # If a line has trailing '\', remove the '\'
                 #    
  t'Hold-append' # branch: Branch conditionally to the label 'Hold-append'
                 #         The condition is that a replacement was made.
                 #         The current pattern-space had a trailing '\' which  
                 #         was replaced, so branch to 'Hold-apend' and append 
                 #         the now-truncated line to the hold-space
                 #
                 # This branching occurs for each (successive) such line. 
                 #
                 # PS. The 't' command may be so named because it means 'on true' 
                 #     (I'm not sure about this, but the shoe fits)  
                 #
                 # Note: Appending to the hold-space introduces a leading '\n'   
                 #       delimiter for each appended line
                 #  
                 #   eg. compare the hex dump of the follow 4 example commands:  
                 #       'x' swaps the hold and patten spaces
                 #
                 #       echo -n "a" |sed -ne         'p' |xxd -p  ## 61 
                 #       echo -n "a" |sed -ne     'H;x;p' |xxd -p  ## 0a61
                 #       echo -n "a" |sed -ne   'H;H;x;p' |xxd -p  ## 0a610a61
                 #       echo -n "a" |sed -ne 'H;H;H;x;p' |xxd -p  ## 0a610a610a61

   # No replacement was made above, so the current pattern-space
   #   (input line) has a "normal" ending.

   x             # Swap the pattern-space (the just-read "normal" line)
                 #   with the hold-space. The hold-space holds the accumulation
                 #   of appended  "stripped-of-backslah" lines

   G             # The pattern-space now holds zero to many "stripped-of-backslah" lines
                 #   each of which has a preceding '\n'
                 # The 'G' command Gets the Hold-space and appends it to 
                 #   the pattern-space. This append action introduces another
                 #   '\n' delimiter to the pattern space. 

   s/\n//g       # Remove all '\n' newlines from the pattern-space

   p             # Print the pattern-space

   s/.*//        # Now we need to remove all data from the pattern-space
                 # This is done as a means to remove data from the hold-space 
                 #  (there is no way to directly remove data from the hold-space)

   x             # Swap the no-data pattern space with the hold-space
                 # This leaves the hold-space re-initialized to empty...
                 # The current pattern-space will be overwritten by the next line-read

   b             # Everything is ready for the next line-read. It is time to make 
                 # an unconditional branch  the to end of process for this line
                 #  ie. skip any remaining logic, read the next line and start the process again.

  :'Hold-append' # The ':' (colon) indicates a label.. 
                 # A label is the target of the 2 branch commands, 'b' and 't'
                 # A label can be a single letter (it is often 'a')
                 # Note;  'b' can be used without a label as seen in the previous command 

    H            # Append the pattern to the hold buffer
                 # The pattern is prefixed with a '\n' before it is appended

END-SED
#######

1
নিউরিনোর সমাধান আসলে বেশ সহজ। হালকা জটিল শেডের কথা বলা, এটি আপনার আগ্রহী হতে পারে
গিলস

2

তবুও অন্য সাধারণ কমান্ড লাইন টুল হবে ed, যা স্থানে ফাইল ডিফল্ট মডিফাই দ্বারা এবং সেইজন্য পাতার ফাইল অনুমতি অপরিবর্তিত (আরও তথ্যের জন্য edদেখুন স্ক্রিপ্ট থেকে ইডি টেক্সট এডিটর দিয়ে সম্পাদনা করা ফাইল )

str='
foo bar \
bash 1 \
bash 2 \
bash 3 \
bash 4 \
baz
dude \
happy
xxx
vvv 1 \
vvv 2 \
CCC
'

# We are using (1,$)g/re/command-list and (.,.+1)j to join lines ending with a '\'
# ?? repeats the last regex search.
# replace ',p' with 'wq' to edit files in-place
# (using Bash and FreeBSD ed on Mac OS X)
cat <<-'EOF' | ed -s <(printf '%s' "$str")
H
,g/\\$/s///\
.,.+1j\
??s///\
.,.+1j
,p
EOF

2

readশেলটি ব্যতীত ব্যবহার করার সময় ব্যাকস্ল্যাশগুলির ব্যাখ্যা করবে এই সত্যটি ব্যবহার করে -r:

$ while IFS= read line; do printf '%s\n' "$line"; done <file
foo bar bash baz
dude happy

নোট করুন যে এটি ডেটাতে অন্য কোনও ব্যাকস্ল্যাশকেও ব্যাখ্যা করবে ।


নাঃ। এটি সমস্ত ব্যাকস্ল্যাশ সরিয়ে ফেলবে না । সাথে চেষ্টা করুনa\\b\\\\\\\\\\\c
আইজাক

@ ইসহাক আহ, সম্ভবত আমার "অন্য কোনও ব্যাকস্ল্যাশ ব্যাখ্যা" বলা উচিত ছিল?
কুসালানন্দ

1

একটি সাধারণ (র) সমাধান যা পুরো ফাইলটিকে মেমরিতে লোড করে:

sed -z 's/\\\n//g' file                   # GNU sed 4.2.2+.

অথবা একটি স্থির সংক্ষিপ্ততর যা বোঝার জন্য কাজ করে (আউটপুট) লাইনগুলি (জিএনইউ সিনট্যাক্স):

sed ':x;/\\$/{N;bx};s/\\\n//g' file

এক লাইনে (POSIX সিনট্যাক্স):

sed -e :x -e '/\\$/{N;bx' -e '}' -e 's/\\\n//g' file

বা জাজক ব্যবহার করুন (যদি ফাইলটি স্মৃতিতে ফিট করার জন্য খুব বড় হয়):

awk '{a=sub(/\\$/,"");printf("%s%s",$0,a?"":RS)}' file

0

@ গিলস সমাধানের উপর ভিত্তি করে ম্যাক সংস্করণটি এর মতো দেখায়

sed ':x
/\\$/{N; s|\\'$'\\n||; tx
}' textfile

যেখানে মূল পার্থক্যটি হল কীভাবে নতুন লাইনের প্রতিনিধিত্ব করা হয় এবং যে কোনও একটিকে এক লাইনে যুক্ত করা এটি ভেঙে যায়


-1

আপনি সিপিপি ব্যবহার করতে পারেন তবে এটি কিছু খালি লাইন তৈরি করে যেখানে এটি আউটপুটকে একীভূত করে এবং কিছু ভূমিকা যা আমি সেডের সাথে সরিয়ে দিয়েছি - সম্ভবত এটি সিপিপি-ফ্ল্যাগ এবং বিকল্পগুলির সাহায্যেও করা যেতে পারে:

echo 'foo bar \
bash \
baz
dude \
happy' | cpp | sed 's/# 1 .*//;/^$/d'
foo bar bash baz
dude happy

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

@ মান্যাটওয়ার্ক: আউটস! :) আমি অবাক হয়ে গিয়েছিলাম যে সেড কমান্ডটি কাজ করেছিল, তবে অবশ্যই সেড কমান্ড ছিল না, তবে ব্যাশ নিজেই ব্যাকস্ল্যাশ-লাইন ব্রেককে পূর্ববর্তী লাইনের ধারাবাহিকতা হিসাবে ব্যাখ্যা করে।
ব্যবহারকারী অজানা

এর cppমতো ব্যবহার করা এখনও আমার পক্ষে লাইনগুলিকে সম্মতি দেয় না। এবং এর ব্যবহার sedঅবশ্যই অপ্রয়োজনীয়। ব্যবহার করুন cpp -P: " -Pপ্রিপ্রোসেসর থেকে আউটপুটে লাইন মার্কারদের প্রজন্মকে বাধা দিন” "- ম্যান সিপিপি
ম্যান্যাটওয়ার্ক

আপনার আদেশ আমার পক্ষে কাজ করে না: cpp: “-P: No such file or directory cpp: warning: '-x c' after last input file has no effect cpp: unrecognized option '-P:' cpp: no input filesএকটি cpp --versionপ্রকাশ cpp (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3- কী? উবুন্টু সিপ্পি প্যাচ করছে? কেন? আমি জিএনইউ পড়তে আশা করতাম ...
ব্যবহারকারী অচেনা

মজাদার. উবুন্টু cppপ্রকৃতপক্ষে লাইনগুলি সামঞ্জস্য করে এবং কিছু ফাঁকা ছেড়ে দেয়। আরও আকর্ষণীয়, এখানে 4.4.3-4ubuntu5.1 একই সংস্করণ গ্রহণ করে -P। তবে এটি কেবল লাইনমার্কারকে সরিয়ে দেয়, খালি লাইনগুলি রয়ে যায়।
manatwork
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.