আউটপুট থেকে রঙগুলি সরানো হচ্ছে


140

আমার কাছে এমন কিছু স্ক্রিপ্ট রয়েছে যা রঙগুলি দিয়ে আউটপুট তৈরি করে এবং আমাকে এএনএসআই কোডগুলি সরানো দরকার।

#!/bin/bash

exec > >(tee log)   # redirect the output to a file but keep it on stdout
exec 2>&1

./somescript

আউটপুটটি (লগ ফাইলে):

java (pid  12321) is running...@[60G[@[0;32m  OK  @[0;39m]

আমি কীভাবে এখানে ইসি অক্ষর রাখি তা জানতাম না, তাই আমি @এটির জায়গায় রেখেছি ।

আমি স্ক্রিপ্টটি এতে পরিবর্তন করেছি:

#!/bin/bash

exec > >(tee log)   # redirect the output to a file but keep it on stdout
exec 2>&1

./somescript | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"

তবে এখন এটি আমাকে দেয় (লগ ফাইলে):

java (pid  12321) is running...@[60G[  OK  ]

আমি কীভাবে এটি অপসারণ করতে পারি @[60G?

পুরো স্ক্রিপ্টের জন্য রঙ সম্পূর্ণরূপে অক্ষম করার কোনও উপায় আছে?


নোড / এনপিএম এর জন্য, আপনি ব্যবহার করতে পারেন strip-ansi: github.com/chalk/strip-ansi
জোশুয়া পিন্টার

উত্তর:


165

উইকিপিডিয়া অনুসারে , [m|K]আপনি যে sedকমান্ডটি ব্যবহার করছেন সেটি বিশেষত m(রঙের কমান্ড) এবং K("রেখার অংশ মুছে ফেলুন" কমান্ড) হ্যান্ডেল করার জন্য তৈরি করা হয়েছে । আপনার স্ক্রিপ্টটি ^[[60Gকোনও লাইনে সমস্ত ঠিক আছে, যা আপনার sedলাইনটি কভার করে না , তা পেতে 60 ( ) এ পরম কার্সার অবস্থান নির্ধারণ করার চেষ্টা করছে ।

(সঠিকভাবে, [m|K]সম্ভবত হওয়া উচিত (m|K)বা [mK], কারণ আপনি কোনও পাইপের চরিত্রের সাথে মেলে চেষ্টা করছেন না But তবে এটি এখন গুরুত্বপূর্ণ নয়))

আপনি যদি আপনার কমান্ডের মধ্যে চূড়ান্ত ম্যাচটি স্যুইচ করেন [mGK]বা (m|G|K), আপনার অতিরিক্ত নিয়ন্ত্রণ অনুক্রমটি ধরতে সক্ষম হওয়া উচিত।

./somescript | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g"

29
বিএসডি / ওএসএক্স ব্যবহারকারীরা: আমাদের কাছে সাধারণত শেডের -r বিকল্প নেই। brew install gnu-sedএকটি সক্ষম সংস্করণ ইনস্টল করা হবে। সাথে চালাও gsed
নিকোলাই এস

1
আমি যদি করি তবে আমি echo "$(tput setaf 1)foo$(tput sgr0) bar" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | cat -Aপেয়েছি: foo^O bar$সুতরাং আমার ধারণা অনুমান করা হয় কিছু চরিত্র সঠিকভাবে মুছে ফেলা হয়নি, তাই না? আপনি কীভাবে সংশোধন করতে জানেন?
এডি 9999

1
@ এডি৯৯৯৯ যতদূর আমি বলতে পারি, পার্থক্যটি হল যে রঙের সেটিংসের জন্য ১ colors টি রঙের ( setafসমর্থন হিসাবে ) মাত্র দুটিটির চেয়ে বেশি পরামিতি প্রয়োজন; আমার regex দুটি সমর্থন করে। প্রথমটির ?জন্য পরিবর্তন করা *উচিত সাহায্য করা উচিত। হ্যান্ডলিং sgr0সম্ভব তবে একটি অনুসন্ধানের ভিত্তিতে এটি সম্ভবত এই হ্যাকি রেজেক্স-ভিত্তিক উত্তরের ক্ষেত্রের বাইরে বাড়বে।
জেফ

ঠিক আছে, আমি একটি উত্তর যুক্ত করেছি যা sed
পাইপটিতে

7
এটি নির্ভরযোগ্যভাবে কাজ করে না কারণ তৃতীয় মান (আলা [38;5;45m) হতে পারে । এই বিকল্প উত্তরটি unix.stackexchange.com/a/55547/168277
davemyron

30

আমি অন্য কোনও উত্তর থেকে ভাল ফলাফল পেতে পারি না, তবে নিম্নলিখিতগুলি আমার পক্ষে কাজ করেছে:

somescript | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g"

যদি আমি শুধুমাত্র নিয়ন্ত্রণের চর "" removed ["অপসারণ করি তবে এটি বাকি রঙের ডেটা যেমন," 33 মি "রেখে দেয়। রঙ কোড এবং "এম" সহ কৌতুকটি করেছে। আমি s / \ x1B // g নিয়ে বিস্মিত হয়েছি কারণ doesn't x1B [31 মি অবশ্যই প্রতিধ্বনি দিয়ে কাজ করে।


6
ওএসএক্সে (বিএসডি সেড) এক্সটেন্ডেড রেজেক্সের -Eপরিবর্তে ব্যবহার করুন -r। আরও এখানে
আসাম্বার

আমাকে প্রতিস্থাপন {1,3}করতে হয়েছিল {,3}(অন্যথায় এটি এখনও কিছু নিয়ন্ত্রণ এড়িয়ে চলেছিল), আপনার সমাধানের জন্য ধন্যবাদ!
ক্রিয়াবিহীন

6
যেহেতু সেগুলি একাধিক সংখ্যা হতে পারে আধা-কলোন দিয়ে পৃথক করা (পটভূমির রঙের জন্য, গা bold়, তির্যক ইত্যাদি ...)। এই আদেশটি আমার পক্ষে কাজ করেছে:sed -r "s/[[:cntrl:]]\[([0-9]{1,3};)*[0-9]{1,3}m//g"
সাইদগনু

এটির (আমি পরীক্ষিত অনেকের মধ্যে) আনসিবল আউটপুট যা অবাফার দিয়ে চালানো হয়েছিল তার সাথে কাজ করেছিল।
মার্টিন

23

আইএমএইচও, এই উত্তরগুলির বেশিরভাগগুলি পালানোর কোডের ভিতরে থাকা সীমাবদ্ধ করতে খুব চেষ্টা করে। ফলস্বরূপ, তারা সাধারণ কোডগুলি [38;5;60m(256 রঙের মোড থেকে অগ্রভাগের এএনএসআই রঙ 60) হারিয়েছে ।

তাদের -rবিকল্পেরও প্রয়োজন যা GNU এক্সটেনশানগুলিকে সক্ষম করে । এগুলি প্রয়োজন হয় না; তারা কেবল রেজেক্সকে আরও ভাল করে পড়তে পারে।

এখানে একটি সহজ উত্তর যা 256-রঙের পালানো পরিচালনা করে এবং নন-জিএনইউ সহ সিস্টেমে কাজ করে sed:

./somescript | sed 's/\x1B\[[0-9;]\+[A-Za-z]//g'

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

ফানসিগুলির জন্য, সমস্ত কল্পনাযোগ্য এএনএসআই অব্যাহতি ক্রমের জন্য এখানে একটি বৃহত্তর এবং আরও সাধারণ (তবে সর্বনিম্ন পরীক্ষিত) সমাধানটি দেওয়া হয়েছে :

./somescript | sed 's/\x1B[@A-Z\\\]^_]\|\x1B\[[0-9:;<=>?]*[-!"#$%&'"'"'()*+,.\/]*[][\\@A-Z^_`a-z{|}~]//g'

(এবং যদি আপনার @ edi9999 এর এসআই সমস্যা থাকে তবে | sed "s/\x0f//g"শেষ পর্যন্ত যোগ করুন ; এটি অনাকাঙ্ক্ষিত চরের হেক্সের পরিবর্তে যে কোনও নিয়ন্ত্রণ চরের জন্য কাজ করে 0f)


এটি একটি Azure আজ ক্লায়েন্ট প্রাকটিকৃত আউটপুট থেকে রঙ স্ট্রিং সুন্দর কাজ করে।
ভলভক্স

ফিক্সড @ এলিগ। দেখা যাচ্ছে এতে বেশ কয়েকটি সমস্যা ছিল, কিছু সম্পাদক আমার সমস্ত ড্যাশগুলি অদ্ভুত ইউনিকোড সংস্করণগুলির সাথে প্রতিস্থাপন করে শুরু করেছিলেন, তবে একগুচ্ছ অনুচিত পলায়ন - |সেডে, ]অক্ষর শ্রেণীর অভ্যন্তরে এবং 'একক উদ্ধৃত বাশ স্ট্রিংয়ে in এটি এখন খুব বেসিক পরীক্ষার ক্ষেত্রে আমার জন্য কাজ করছে।
meustrus

20

ম্যাক ওএসএক্স বা বিএসডি ব্যবহারের জন্য

./somescript | sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g'

1
আশ্চর্যের বিষয়, এটি ডেবিয়ানদের পক্ষে ভাল কাজ করেছে তবে উপরের অন্যরা তা করেন নি।
cy8g3n

এটি একটি আংশিকভাবে কাজ করে। তবে, আমি যদি এক্সেলে কোনও ফাইল খুলি, আমি এখনও এই বিশেষ চরিত্রটি দেখতে পাচ্ছি? " প্রতিটি লাইন শেষে।
doudy_05

@ doudy_05 -Eপ্রসারিত regexp সক্ষম করতে সেডের জন্য পতাকা প্রেরণের চেষ্টা করুন ।
আলেকজান্ডার জিঙ্কেঙ্কো

14

আমারও সমস্যা ছিল যে মাঝে মাঝে এসআই চরিত্রটি উপস্থিত হয়েছিল।

এই ইনপুটটির সাথে উদাহরণস্বরূপ এটি ঘটেছে: echo "$(tput setaf 1)foo$(tput sgr0) bar"

এসআই চরিত্রটি (শিফ্ট ইন) (0x0f) কেটে ফেলার একটি উপায় এখানে রয়েছে

./somescript | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | sed "s/\x0f//g"

2
নিশ্চিত নয় যে এই উত্তরটি কেন এত কম .ণ পেয়েছে। এটি আমার জন্য একমাত্র কাজ করছে ...
m8mble

8

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

./somescript | tr -d '[:cntrl:]'

32
হঠাৎ এটি নতুন লাইনগুলিও সরিয়ে ফেলবে
রুक्स

হ্যাঁ, এলএফ এবং সিআর (কোড) হ'ল নিয়ন্ত্রণ কোড; যদি আপনার একাধিক লাইনে আগ্রহী হয় তবে এটি সমাধান হতে পারে না। যেহেতু মনে হচ্ছে আপনি কোনও জাভা প্রোগ্রাম চালাচ্ছেন আমি অনুমান করব যে সেখান থেকে রঙগুলি পরিচালনা করা হয়েছে; অন্যথায় আপনাকে আপনার কনসোল সেটআপ (যেমন টার্মিনাল সেটিংস / রঙ পরিকল্পনা) এবং / অথবা প্রতিটি বর্ণের 'রং' সমর্থন করে এমন বিকল্পগুলির দিকে নজর দিতে হবে, যেমন ls --color = never
Dale_Reagan

3
আমি এই উত্তরটি তার কমনীয়তার জন্য পছন্দ করি, এমনকি এটি কেবল রঙ অপসারণের চেয়ে আরও বেশি কিছু করে। ধন্যবাদ!
জোহান ফিলিপ স্ট্র্যাথাউসেন

7
এটি আসলে কোডগুলি সেখানে দেয়, ls -l + আপনার কমান্ড দেখুন:rwxr-xr-x 1 tokra admin 22 Oct 18 14:21 [0m[01;36m/usr/local/opt/gradle[0m -> [01;34m../Cellar/gradle/4.2.1[0m/
ক্রা

7

আমারও একই সমস্যা ছিল। আমি যে সকল সমাধান পেয়েছি সেগুলি রঙের কোডগুলির জন্য ভাল কাজ করেছে তবে "$(tput sgr0)"(বৈশিষ্ট্যগুলি পুনরায় সেট করে) যোগ করা অক্ষরগুলি সরিয়ে দেয় না ।

উদাহরণস্বরূপ, ডেভমায়রনের দ্বারা মন্তব্যে সমাধানটি নীচের উদাহরণে ফলাফলটির স্ট্রিংয়ের দৈর্ঘ্য নয়, 6 নয়:

#!/usr/bin/env bash

string="$(tput setaf 9)foobar$(tput sgr0)"
string_sed="$( sed -r "s/\x1B\[[0-9;]*[JKmsu]//g" <<< "${string}" )"
echo ${#string_sed}

সঠিকভাবে কাজ করার জন্য, sgr0(" \E(B") যোগ করা ক্রমটি মেলানোর জন্য রেজেক্সকে প্রসারিত করতে হবে :

string_sed="$( sed -r "s/\x1B(\[[0-9;]*[JKmsu]|\(B)//g" <<< "${string}" )"

@ জারোডিভ - সর্বাধিক বোধগম্য পদ্ধতির জন্য ধন্যবাদ এই বিষয়টিতে প্রদত্ত সমস্ত উত্তর কেবলমাত্র এএনএসআই / ভিটি 100 কন্ট্রোল সিক্যুয়েন্সের সাথে ডিল করে (উদা: "\ ই [৩১ মিঃ হেলো ওয়ার্ল্ড \ ই [০ মি"), তবে টিপিইউটি পাঠ্য বিন্যাসের কারণে সৃষ্ট কোনও কিছুর পুনরুদ্ধার করবেন না (উদাহরণস্বরূপ: tput smso / tput setaf X / টিপুট আরএমএসো / টিপুট এসজিআর0)। ফলস্বরূপ সমস্ত 'সেড' মৃত্যুদন্ড কার্যকর করার পরে লগগুলিতে আরও কিছু বিশৃঙ্খলা বাকি ছিল। এটি আমার ব্যবহারের ক্ষেত্রে খাঁটি সমাধান!
ফেসবুকে

5

একটি পাঠ্য স্ট্রিম থেকে সাধারণ এএনএসআই কোডগুলি ফিল্টার-আউট করার জন্য খাঁটি বাশে অনেক সহজ কাজ:

# Strips common ANSI codes from a text stream

shopt -s extglob # Enable Bash Extended Globbing expressions
ansi_filter() {
  local line
  local IFS=
  while read -r line || [[ "$line" ]]; do
    echo "${line//$'\e'[\[(]*([0-9;])[@-n]/}"
  done
}

দেখা:

  1. লিনাক্সজার্নাল ডটকম: বর্ধিত গ্লোববিং
  2. gnu.org: ব্যাস প্যারামিটার এক্সপেনশন

1
এটি কাজ করে না। সঙ্গে পরীক্ষা tldr। (যদিও আমি জেডএস ব্যবহার করি তাই এটিও এর কারণ হতে পারে))
হ্যাপিফ্রিজ

প্রকৃতপক্ষে, জ্যাশ বাশের বর্ধিত গ্লোবিং বুঝতে পারবে না extglobবা সম্ভবত এটি পুরোপুরি স্ট্রিং প্রতিস্থাপনও বুঝতে পারবে না।
Léa Gris

আমি zsh এর এক্সটেনডগ্লোব সক্ষম করেছিলাম ... স্ট্রিং প্রতিস্থাপনটিও পোস্টিক হওয়া উচিত?
শুক্রবার

স্ট্রিং প্রতিস্থাপন POSIX নয়। আপনি sedএখানে উল্লিখিত যে কোনও বিকল্প পদ্ধতি ব্যবহার করতে পারেন যা Zsh এর সাথে কাজ করবে।
লায়া গ্রিস

এই সমাধানটিতে পাঠ্যটি লাইন-বাফার করার সুবিধা রয়েছে। আমি সেড দিয়ে চেষ্টা করেছি তবে এটি আমার পাইপটিকে ব্লক-বাফার করছে।
গিলারমো প্রান্দি

3

@ জেফ-বোমন এর সমাধান আমাকে রঙিন কোডগুলির কয়েকটি থেকে মুক্তি দিতে সহায়তা করেছে। আরও কিছু অপসারণের জন্য আমি রেগেক্সে আরও একটি ছোট অংশ যুক্ত করেছি:

sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" # Original. Removed Red ([31;40m[1m[error][0m)
sed -r "s/\x1B\[([0-9];)?([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" # With an addition, removed yellow and green ([1;33;40m[1m[warning][0m and [1;32;40m[1m[ok][0m)
                ^^^^^^^^^
                remove Yellow and Green (and maybe more colors)

2

এখানে একটি খাঁটি বাশ সমাধান।

হিসাবে সংরক্ষণ করুন strip-escape-codes.sh, এক্সিকিউটেবল করুন এবং তারপরে চালান <command-producing-colorful-output> | ./strip-escape-codes.sh

নোট করুন যে এটি সমস্ত এএনএসআই এর অব্যাহতি কোড / সিকোয়েন্সগুলি বাদ দেয়। আপনি শুধুমাত্র রং স্ট্রিপ করতে চান তাহলে, প্রতিস্থাপন [a-zA-Z]সঙ্গে "m"

বাশ> = 4.0:

#!/usr/bin/env bash

# Strip ANSI escape codes/sequences [$1: input string, $2: target variable]
function strip_escape_codes() {
    local _input="$1" _i _char _escape=0
    local -n _output="$2"; _output=""
    for (( _i=0; _i < ${#_input}; _i++ )); do
        _char="${_input:_i:1}"
        if (( ${_escape} == 1 )); then
            if [[ "${_char}" == [a-zA-Z] ]]; then
                _escape=0
            fi
            continue
        fi
        if [[ "${_char}" == $'\e' ]]; then
            _escape=1
            continue
        fi
        _output+="${_char}"
    done
}

while read -r line; do
    strip_escape_codes "${line}" line_stripped
    echo "${line_stripped}"
done

<< 4.0:

#!/usr/bin/env bash

# Strip ANSI escape codes/sequences [$1: input string, $2: target variable]
function strip_escape_codes() {
    local input="${1//\"/\\\"}" output="" i char escape=0
    for (( i=0; i < ${#input}; ++i )); do         # process all characters of input string
        char="${input:i:1}"                       # get current character from input string
        if (( ${escape} == 1 )); then             # if we're currently within an escape sequence, check if
            if [[ "${char}" == [a-zA-Z] ]]; then  # end is reached, i.e. if current character is a letter
                escape=0                          # end reached, we're no longer within an escape sequence
            fi
            continue                              # skip current character, i.e. do not add to ouput
        fi
        if [[ "${char}" == $'\e' ]]; then         # if current character is '\e', we've reached the start
            escape=1                              # of an escape sequence -> set flag
            continue                              # skip current character, i.e. do not add to ouput
        fi
        output+="${char}"                         # add current character to output
    done
    eval "$2=\"${output}\""                       # assign output to target variable
}

while read -r line; do
    strip_escape_codes "${line}" line_stripped
    echo "${line_stripped}"
done

ঠিক আছে, এই সমাধানটি আরও কম জটিল হতে পারে।
আলেকজান্ডার জিঙ্কেঙ্কো

1

বিতর্কিত ধারণাটি হ'ল এই প্রক্রিয়া পরিবেশের জন্য টার্মিনাল সেটিংস পুনরায় কনফিগার করা প্রক্রিয়াটি যাতে জানতে দেয় যে টার্মিনাল রঙ সমর্থন করে না।

এরকম কিছু TERM=xterm-mono ./somescriptআমার মনে আসে। আপনার নির্দিষ্ট ওএস এবং আপনার স্ক্রিপ্টের টার্মিনাল রঙ সেটিংস বোঝার ক্ষমতা সহ ওয়াইএমএমভি।


-7

এটি আমার পক্ষে কাজ করে:

./somescript | cat

3
এটি কীভাবে somescriptবাস্তবায়িত হয় তার উপর নির্ভর করে । এটি বা এটি সনাক্ত করতে পারে না যে এর স্ট্যান্ডার্ড আউটপুটটি একটি tty। (অপরাধীদের শব্দগুলি প্রোগ্রামে আসলে হার্ড-কোড টার্মিনাল-নির্দিষ্ট এ্যাসেপ কোডগুলি করে এবং অন্য টার্মিনালগুলিতে বা স্ক্রিপ্টগুলিতে ব্যবহার করার সময় ভয়াবহভাবে ভেঙে যায়)।
টবির গতি

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