`কলাম -t` এর মতো কমান্ড যা পরিবর্তে আউটপুটে বিভাজক রাখে


17

আমি একটি সাধারণ টেবিল সম্পাদনা করছি। আমি এটি সুন্দরভাবে ফর্ম্যাট করতে চাই। আমি ব্যবহার করতে পারে যদিও tbl, latexবা অনুরূপ, এই Overkill বলে মনে হয় - প্লেইন টেক্সট সত্যিই যথেষ্ট। এটি সহজ হিসাবে আমি পাশাপাশি উত্স আউটপুট হতে পারে। উত্সটিও দেখতে খুব ভাল হওয়া উচিত। এটি মনে হয় এটির জন্য একটি নিখুঁত কাজ হওয়া উচিত column -s '|' -t- এটি বিভাজনকারীদের সন্ধান করে এবং প্রতিটি কলামের সর্বাধিক প্রস্থ অনুসারে স্বয়ংক্রিয়ভাবে ফাঁকা স্থান সন্নিবেশ করায়। দুর্ভাগ্যক্রমে, এটি বিভাজনকারীদের মোছা করে, তাই আমি আরও সম্পাদনার পরে এটিকে পুনরায় চালিত করতে পারি না। এমন কোনও ভাল পাঠ্য-প্রক্রিয়াকরণ সরঞ্জাম রয়েছে যা আদর্শভাবে এই কাজটি করতে পারে, যাতে এটি আউটপুটটি ইনপুট হিসাবে কাজ করে? নাকি আমার নিজের লেখার দরকার আছে?

সম্পাদনা: আমি যা চাই তার একটি উদাহরণ এখানে:

foo |   bar | baz
abc def | 12 | 23456

হয়ে উঠতে হবে

foo     | bar | baz
abc def | 12  | 3456

' 'বিভাজক এবং স্পেসার উভয়ই কখন দুর্দান্তভাবে column -tকাজ করে। তবে আমার আইটেমগুলির মধ্যে স্পেস রয়েছে তাই আমি এটি ব্যবহার করতে পারি না। স্পেসারগুলি পৃথককারীদের থেকে পৃথক হওয়া জিনিসগুলিকে জটিল করে তোলে। আমি মনে করি যে বিভাজনের পাশে যখন তাদের বিভাজক চরিত্র হিসাবে বিবেচনা করা কার্যকর হবে তবে এটি সেভাবে নয় column -s '|' -t(যদিও সম্ভবত বর্তমান আচরণটিও কার্যকর।


আপনি ইমাস অরগ-মোড ব্যবহার করতে পারেন। টেবিল সমর্থনটি কার্যত দক্ষতার মতো স্প্রেডশিট সরবরাহ করে বেশ আশ্চর্যজনক।
বনাম

আমি যেটাকে যুক্তিসঙ্গত বলে মনে করব ঠিক তেমন সাধারণ নয়, তবে বিশেষত লানক্রাও / সমস্ত-this/2008/08/ tables- for-markdown- এবং-textmateমার্কডাউন টেবিলের জন্য একটি অজগর প্রোগ্রাম রয়েছে
WNOise

এটি এমন একটি সমস্যা যা আমি কমপক্ষে প্রতি দুই সপ্তাহের মতো ছুঁড়ে ফেলি। printfপ্রতিবার হোলোকাস্টের বাইপাসের একমাত্র কার্যকর সমাধান , যা আমি এখনও অবধি খুঁজে পেয়েছি, যা @ডেটাতে একটি অনন্য চর (যেমন ) যুক্ত করছে, এবং এর ... | column -s@ -tপরে ব্যবহার করবে ।
sjas

উত্তর:


17

আপনার সমস্যাটি কী তা আমি সঠিকভাবে বুঝতে পারছি কিনা তা নিশ্চিত নই। তবে, এটি কি অতিরিক্ত টেম্পোরাল বিভাজক যুক্ত করে সমাধান করা যায়? অতএব আপনি দ্বিতীয় বিভাজকটি পৃথক পৃথক পৃথক পৃথক পৃথকীকরণটি চিহ্নিত করতে ব্যবহার করতে পারেন original

এই উদাহরণটি দেখুন যেখানে আমি প্রতিটি "|" এর সাথে একটি "@" যুক্ত করেছি সুতরাং কলাম কমান্ডের ইনপুটটি হবে "xxx @ | yyyy"। কলাম "@" রেখে "@" প্রক্রিয়াকরণ করবে অস্পৃষ্ট:

~$ echo "foo | this is some text | bar" | sed 's/|/@|/g'  | column -s '@' -t
foo   | this is some text   | bar

চালাক। প্রায় আমি যা চাই তা করি এবং প্রকৃতপক্ষে আমি যা বলেছিলাম তা করে - বিভাজকগুলিকে ভিতরে রেখে দেয় I আমি চাই সত্যিকারের বিভাজকের পাশের স্পেসগুলি এখানে ঠিক ঠিক না করে বরং সামঞ্জস্য করতে সক্ষম হোক।
অগস্ট

@ নোনায়েস: sed 's/ *| */@| /g'পরিবর্তে ব্যবহার করুন
স্টাফেন গিমেনেজ

@ স্টাফেন গিমেনেজ: এবং সংশোধন করার sed 's/ |/|/g'পরে columnঅতিরিক্ত স্পেস যুক্ত করা হয়েছে। আমাদের এখন একটি সমাধান রয়েছে যা আমার পক্ষে যথেষ্ট ভাল কাজ করে। (যদিও এটি যদি অতিরিক্ত অতিরিক্ত চরিত্রের উপর নির্ভর না করে তবে এটি চমৎকার লাগবে one যদি
কোনওটি

3
@ ননয়েস: @ এর পরিবর্তে আপনি এমন কিছু ব্যবহার করতে পারেন যা সাধারণত পাঠ্যগুলিতে কম ASCII মান হিসাবে প্রদর্শিত না হয়। $ '\ x01' ... (তবে $ '\ x00' নয়) ...
পিটার.ও

6

যখন আপনি প্রশ্ন জিজ্ঞাসা কিন্তু এই উপলব্ধ ছিল না বনাম হিসাবে। 2.23 column থেকে util-linuxআপনি মাধ্যমে আউটপুট বিভাজক বৈশিষ্ট্য নির্ধারণ করতে পারবেন

   -o, --output-separator string
          Specify the columns delimiter for table output (default is two spaces).

সুতরাং সহজভাবে চালান:

 column -s '|' -o '|' -t infile

লক্ষ্য করুন যে util-linuxসংস্করণটি লেখার সময় উবুন্টু 18.04 (এবং সম্ভবত অন্যান্য দেবাইনের উদ্ভূত ডিগ্রোস) তে উপলব্ধ নয়। কেবল bsdmainutilsসংস্করণ উপলব্ধ। bsdmainutilsসংস্করণ আউটপুট বিন্যাস সমর্থন করে না।
htaccess

5

এখানে একটি বাশ স্ক্রিপ্ট আছে। এটি 'কলাম -t` ব্যবহার করে না, এবং বিভাজকটি ঠিক আইএফএসের মতো পরিচালনা করা হয়, কারণ এটি আইএফএস (বা কমপক্ষে, আইএফএসের অভ্যন্তরীণ সংস্করণ) ... ডিফল্ট ডিলিমিটারটি হ'ল' \ t '

এই স্ক্রিপ্টটি পুরোপুরি ডানদিকের ক্ষেত্রটিকে প্যাড করে।
'কলাম' এটি করে না।
সমস্ত কলাম কমানোর মাধ্যমে, এই স্ক্রিপ্টটি
সহজেই একটি টেবিল ফ্রেম তৈরি করতে পরিবর্তন করা যেতে পারে ।

বিঃদ্রঃ. ইনপুট ফাইলটি দু'বার প্রক্রিয়া করা প্রয়োজন
('কলাম' এছাড়াও এটি করতে হবে)
প্রথম পাসটি কলাম সর্বাধিক প্রস্থ পাওয়া।
দ্বিতীয় পাসটি ক্ষেত্রগুলি প্রসারিত করতে হবে (প্রতি কলামে)

কিছু বিকল্প যুক্ত করা হয়েছে এবং একটি সুস্পষ্ট বাগ স্থির করা হয়েছে (পরিবর্তনশীলগুলির নামকরণ :(

  • -l যেকোন ইন্ডেন্টেড ক্ষেত্রের বাম ট্রিম হোয়াইটস্পেস
  • -আর প্রশস্ত পাঠ্যের চেয়ে ডান ট্রিম সাদা স্থান প্রশস্ত করুন (কলামের জন্য)
  • -b উভয় -l এবং -r
  • -L বাম আউটপুট ডিলিমিটার যুক্ত করা হয়
  • -R ডান আউটপুট ডিলিমিটার যুক্ত করা হয়
  • -বি উভয় -L এবং -আর
  • -S আউটপুট পৃথক চয়ন করুন

#!/bin/bash
#
#   script [-F sep] [file]
#
#   If file is not specified, stdin is read 
#    
# ARGS ######################################################################
l=;r=;L=;R=;O=;F=' ' # defaults
for ((i=1;i<=${#@};i++)) ;do
  case "$1" in
    -- ) shift 1;((i--));break ;;
    -l ) l="-l";shift 1;((i-=1)) ;;        #  left strip whitespace
    -r ) r="-r";shift 1;((i-=1)) ;;        # right strip whitespace
    -b ) l="-l";r="-r";shift 1;((i-=1)) ;; # strip  both -l and -r whitespace
    -L ) L="-L";shift 1;((i-=1)) ;;        #  Left output delimiter is added
    -R ) R="-R";shift 1;((i-=1)) ;;        # Right output delimiter is added
    -B ) L="-L";R="-R";shift 1;((i-=1)) ;; # output Both -L and -R delimiters
    -F ) F="$2";shift 2;((i-=2)) ;; # source separator
    -O ) O="$2";shift 2;((i-=2)) ;; # output  separator. Default = 1st char of -F 
    -* ) echo "ERROR: invalid option: $1" 1>&2; exit 1 ;;
     * ) break ;;
  esac
done
#
if  [[ -z "$1" ]] ;then # no filename, so read stdin
  f="$(mktemp)"
  ifs="$IFS"; IFS=$'\n'; set -f # Disable pathname expansion (globbing)
  while read -r line; do
    printf "%s\n" "$line" >>"$f"
  done
  IFS="$ifs"; set +f # re-enable pathname expansion (globbing)
else
  f="$1"
fi
[[ -f "$f" ]] || { echo "ERROR: Input file NOT found:" ;echo "$f" ;exit 2 ; }
[[ -z "$F" ]] && F=' '        # input Field Separator string
[[ -z "$O" ]] && O="$F"       # output Field Separator
                 O="${O:0:1}" #   use  single char only

# MAIN ######################################################################
max="$( # get max length of each field/column, and output them
  awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" '
    BEGIN { if (F!="") FS=F }
    { for (i=1;i<=NF;i++) { 
        if (l=="-l") { sub("^[ \t]*","",$i) }
        if (r=="-r") { sub("[ \t]*$","",$i) }
        len=length($i); if (len>max[i]) { max[i]=len } 
        if (i>imax) { imax=i } 
      } 
    }
    END { for(i=1;i<=imax;i++) { printf("%s ",max[i]) } }
  ' "$f" 
)"

awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" -v_max="$max" '
  BEGIN { if (F!="") FS=F; cols=split(_max,max," ") }
  { # Bring each field up to max len and output with delimiter
    printf("%s",L=="-L"?O:"")
    for(i=1;i<=cols;i++) { if (l=="-l") { sub("^[ \t]*","",$i) } 
                           if (r=="-r") { sub("[ \t]*$","",$i) }
      printf("%s%"(max[i]-length($i))"s%s",$i,"",i==cols?"":O) 
    } 
    printf("%s\n",R=="-R"?O:"")
  }
' "$f"

# END #######################################################################    
if  [[ -z "$1" ]] ;then # no filename, so stdin was used
  rm "$f"   # delete temp file
fi
exit

সুন্দরভাবে সম্পন্ন. অবশ্যই, আমি এমন কিছু প্রত্যাশা করছিলাম যার জন্য আসলে কোনও নতুন প্রোগ্রাম লেখার প্রয়োজন হবে না।
22:58


1

এটি হমন্তোলিউয়ের উত্তরে একটি দ্বি-পাসের টুইট , যা ইনপুট ডেটা থেকে অনুমান করে হার্ড ডিলিমিটারের কোড প্রয়োজন হয় না।

  1. স্থানগুলি দ্বারা বেষ্টিত একক অ-অক্ষরীয় অক্ষরের জন্য পার্স ইনপুট, সর্বাধিক সাধারণ অনুসারে বাছাই করুন এবং ধরে নিন যে সর্বাধিক সাধারণ চরিত্রটি হ'ল ডিলিমিটার $d
  2. হমনোলির জবাব হিসাবে কম-বেশি এগিয়ে যান , তবে পিটারওর মন্তব্য অনুসারে , ASCII NULL প্যাডিং হিসাবে ব্যবহার করুন।@

কোডটি এমন একটি ফাংশন যা কোনও ফাইল নাম গ্রহণ করে, বা অন্যথায় এসটিডিআইএন থেকে ইনপুট :

algn() { 
    d="$(grep -ow '[^[:alnum:]]' "${1:-/dev/stdin}"  | \
         sort | uniq -c | sort -rn | sed -n '1s/.*\(.$\)/\1/p')" ;
    sed "s/ *$d */\x01$d /g" "${1:-/dev/stdin}"  | column -s $'\001' -t ;
}

algn foo(বা এছাড়াও algn < foo) এর আউটপুট :

foo      | bar  | baz
abc def  | 12   | 23456

এক বছর পরে এটি দেখে মনে হচ্ছে যে STDIN অনুরোধটি কাজ করতে পারে না এবং করা উচিত নয় কারণ এটি দুটিবার STDIN ব্যবহার করে । বড় ফাইল (প্রায় ৮০ মিলিয়ন লাইন) এর সাথে পরীক্ষা করা ইঙ্গিত দেয় যে এটি দৃশ্যত সঠিকভাবে কাজ করে। হুম ...
এজিসি

0

সাধারণ কমান্ডটি প্রয়োগ করতে হেমন্তোলিউ সম্পর্কে ধারণা ব্যবহৃত হয়েছে :

#! /bin/bash
delim="${1:-,}"
interm="${2:-\~}"
sed "s/$delim/$interm$delim/g" | column -t -s "$interm" | sed "s/  $delim/$delim/g"

মন্তব্য:

  • ${1:-,}- এটি ,ডিফল্ট হিসাবে প্রথম যুক্তি
  • প্রথমটি sedএকটি মধ্যবর্তী প্রতীক সন্নিবেশ করায় ( $intermদ্বিতীয় তর্ক বা ~ডিফল্টরূপে)
  • তারপরে columnমধ্যবর্তী প্রতীকটি ফাঁকা স্থানগুলির সাথে প্রতিস্থাপন করে যা প্রান্তিককরণ করে
  • দ্বিতীয়টি কমান্ডের sedপরে অপ্রয়োজনীয় স্থানগুলি পরিষ্কার করেcolumn

ব্যবহারের উদাহরণ:

$ echo "
a: bb: cccc
aaaa: b : cc
" | align :

a   : bb: cccc
aaaa: b : cc

এটি আদর্শ আদর্শের ক্ষেত্রে এটিও বেশ ভাল: আপনি এটি বেশ কয়েকবার প্রয়োগ করতে পারেন এবং একই ফলাফল পেতে পারেন (উদাহরণস্বরূপ আপনি যখন ভিমে সম্পাদনা করবেন এবং পুনরায় সাইন ইন করুন)।

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