সেড - একটি ফাইলের একটি স্ট্রিং (কমা) এর শেষ ঘটনাটি সরিয়ে ফেলবেন?


15

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

...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0],
]

পছন্দসই আউটপুট

...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0]
]

নিম্নলিখিত সিড কমান্ডটি প্রতি লাইন শেষ ঘটনাটি মুছবে, তবে আমি প্রতি ফাইল চাই।

sed -e 's/,$//' foo.csv

বা এই কাজ করে না

sed '$s/,//' foo.csv

কমা কি সর্বদা দ্বিতীয় থেকে শেষ লাইনে থাকে?
1024

হ্যাঁ, দ্বিতীয় থেকে শেষ পংক্তিতে
স্পুডারটি

উত্তর:


12

ব্যবহার awk

যদি কমাটি সর্বদা দ্বিতীয় থেকে শেষ লাইনের শেষে থাকে:

$ awk 'NR>2{print a;} {a=b; b=$0} END{sub(/,$/, "", a); print a;print b;}'  input
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0]
]

ব্যবহার awkএবংbash

$ awk -v "line=$(($(wc -l <input)-1))" 'NR==line{sub(/,$/, "")} 1'  input
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0]
]

ব্যবহার sed

$ sed 'x;${s/,$//;p;x;};1d'  input
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0]
]

ওএসএক্স এবং অন্যান্য বিএসডি প্ল্যাটফর্মগুলির জন্য চেষ্টা করুন:

sed -e x -e '$ {s/,$//;p;x;}' -e 1d  input

ব্যবহার bash

while IFS=  read -r line
do
    [ "$a" ] && printf "%s\n" "$a"
    a=$b
    b=$line
done <input
printf "%s\n" "${a%,}"
printf "%s\n" "$b"

সম্ভবত এটি কারণ আমি একটি ম্যাক এ আছি, তবে sed: 1: "x;${s/,$//;p;x}; 2,$ p": extra characters at the end of x command
সেড

@ স্পডার হ্যাঁ, ওএসএক্সের বিএসডি রয়েছে sedএবং এটি প্রায়শই সূক্ষ্ম উপায়ে আলাদা হয়। এটি পরীক্ষা করার জন্য আমার কাছে OSX এ অ্যাক্সেস নেই, তবে দয়া করে চেষ্টা করুনsed -n -e x -e '${s/,$//;p;x;}' -e '2,$ p' input
1024

হ্যাঁ, দ্বিতীয়টি ম্যাক
স্পুডার

4

কেবলমাত্র আপনি নীচের পার্ল ওয়ান-লাইনার কমান্ডটি ব্যবহার করতে পারেন।

perl -00pe 's/,(?!.*,)//s' file

ব্যাখ্যা:

  • , কমা দিয়ে মেলে।
  • (?!.*,)নেতিবাচক বর্ণনহীন দৃser়ভাবে দাবি করে যে সেই মিলিত কমা পরে কোনও কমা হবে না। সুতরাং এটি শেষ কমাটি মিলবে।
  • sএবং সর্বাধিক sআমদানিকৃত জিনিস হ'ল ডটল মোডিফায়ার যা ডটকে এমনকি নতুন লাইনের অক্ষরগুলির সাথে মিলে যায়।

2
এছাড়াও আপনি কাজ করতে পারে: perl -0777 -pi -e 's/(.*),(.*?)/\1\2/s'। এটি কাজ করে কারণ প্রথমটি .*লোভী, এবং দ্বিতীয়টি নয়।
ওলেগ ভাস্কেভিচ

4
lcomma() { sed '
    $x;$G;/\(.*\),/!H;//!{$!d
};  $!x;$s//\1/;s/^\n//'
}

এটি ,কোনও ইনপুট ফাইলে কেবলমাত্র শেষ ঘটনাটি সরিয়ে ফেলতে পারে - এবং এটি এখনও মুদ্রণ করবে যেখানে একটি ,ঘটে না। মূলত, এটি লাইনের ক্রমগুলিকে বাফার করে যাতে কমা থাকে না।

যখন এটি কোনও কমাটির মুখোমুখি হয় তখন এটি হোল্ড বাফারের সাথে বর্তমান লাইন বাফারকে অদলবদল করে এবং সেভাবে একই সাথে শেষ কমা থেকে ঘটে যাওয়া সমস্ত লাইন মুদ্রণ করে এবং এর হোল্ড বাফারকে মুক্ত করে।

আমি আমার ইতিহাস ফাইলটি খনন করছিলাম এবং এটি পেয়েছি:

lmatch(){ set "USAGE:\
        lmatch /BRE [-(((s|-sub) BRE)|(r|-ref)) REPL [-(f|-flag) FLAG]*]*
"       "${1%"${1#?}"}" "$@"
        eval "${ZSH_VERSION:+emulate sh}"; eval '
        sed "   1x;     \\$3$2!{1!H;\$!d
                };      \\$3$2{x;1!p;\$!d;x
                };      \\$3$2!x;\\$3$2!b'"
        $(      unset h;i=3 p=:-:shfr e='\033[' m=$(($#+1)) f=OPTERR
                [ -t 2 ] && f=$e\2K$e'1;41;17m}\r${h-'$f$e\0m
                f='\${$m?"\"${h-'$f':\t\${$i$e\n}\$1\""}\\c' e=} _o=
                o(){    IFS=\ ;getopts  $p a "$1"       &&
                        [ -n "${a#[?:]}" ]              &&
                        o=${a#-}${OPTARG-${1#-?}}       ||
                        ! eval "o=$f;o=\${o%%*\{$m\}*}"
        };      a(){    case ${a#[!-]}$o in (?|-*) a=;;esac; o=
                        set $* "${3-$2$}{$((i+=!${#a}))${a:+#-?}}"\
                                ${3+$2 "{$((i+=1))$e"} $2
                        IFS=$;  _o=${_o%"${3+$_o} "*}$*\
        };      while   eval "o \"\${$((i+=(OPTIND=1)))}\""
                do      case            ${o#[!$a]}      in
                        (s*|ub)         a s 2 ''        ;;
                        (r*|ef)         a s 2           ;;
                        (f*|lag)        a               ;;
                        (h*|elp)        h= o; break     ;;
                esac;   done;   set -f; printf  "\t%b\n\t" $o $_o
)\"";}

এটা আসলে বেশ ভাল। হ্যাঁ, এটি ব্যবহার করে evalতবে এটি তার যুক্তিগুলির সংখ্যাসমুহ রেফারেন্সের বাইরে এটি কোনও কিছুতেই পাস করে না। এটি sedশেষ ম্যাচটি পরিচালনা করার জন্য স্বেচ্ছাসেবী স্ক্রিপ্টগুলি তৈরি করে । আমি তোমাকে দেখাব:

printf "%d\" %d' %d\" %d'\n" $(seq 5 5 200) |                               
    tee /dev/fd/2 |                                                         
    lmatch  d^.0     \  #all re's delimit w/ d now                           
        -r '&&&&'    \  #-r or --ref like: '...s//$ref/...'      
        --sub \' sq  \  #-s or --sub like: '...s/$arg1/$arg2/...'
        --flag 4     \  #-f or --flag appended to last -r or -s
        -s\" \\dq    \  #short opts can be '-s $arg1 $arg2' or '-r$arg1'
        -fg             #tacked on so: '...s/"/dq/g...'                     

যে stderr নিম্নলিখিত মুদ্রণ। এটি lmatchএর ইনপুটটির অনুলিপি :

5" 10' 15" 20'
25" 30' 35" 40'
45" 50' 55" 60'
65" 70' 75" 80'
85" 90' 95" 100'
105" 110' 115" 120'
125" 130' 135" 140'
145" 150' 155" 160'
165" 170' 175" 180'
185" 190' 195" 200'

ফাংশনের evalএড সাবশেল একবারে তার সমস্ত আর্গুমেন্টের মাধ্যমে পুনরাবৃত্তি করে। এটি তাদের উপর দিয়ে হাঁটার সময় এটি প্রতিটি পাল্টানোর প্রসঙ্গে নির্ভর করে যথাযথভাবে একটি কাউন্টারকে পুনরাবৃত্তি করে এবং পরবর্তী পুনরাবৃত্তির জন্য অনেকগুলি আর্গুমেন্ট এড়িয়ে যায়। তারপরে এটি আর্গুমেন্ট অনুসারে কয়েকটি জিনিসের একটি করে:

  • প্রতিটি বিকল্পের জন্য বিকল্পটি পার্সার যুক্ত $aকরে $o। প্রক্রিয়াকৃত প্রতিটি আরগের জন্য আরগের গণনা দ্বারা বাড়ানো $aমানটির উপর ভিত্তি করে নির্ধারিত হয় $i$aনিম্নলিখিত দুটি মানগুলির মধ্যে একটি নির্ধারিত হয়:
    • a=$((i+=1)) - যদি সংক্ষিপ্ত-বিকল্পের সাথে তার যুক্তি যুক্ত না হয় বা বিকল্পটি দীর্ঘ হয় তবে এটি নির্ধারিত হয়।
    • a=$i#-?- এই যদি বিকল্প একটি সংক্ষিপ্ত এক এবং নির্ধারিত হয় না তার ARG এটি যোগ করা আছে।
    • a=\${$a}${1:+$d\${$(($1))\}}- প্রাথমিক অ্যাসাইনমেন্ট নির্বিশেষে, $aএর মান সর্বদা ব্রেসগুলিতে আবৃত থাকে এবং - একটি -sক্ষেত্রে - কখনও কখনও $iআরও একটি বাড়ানো হয় এবং অতিরিক্তভাবে সীমিত ক্ষেত্র যুক্ত হয়।

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

কার্যক্ষেত্রে ফাংশনের কিছু ডিবাগ আউটপুট এখানে রয়েছে:

... sed "   1x;\\$2$1!{1!H;\$!d
        };      \\$2$1{x;1!p;\$!d;x
        };      \\$2$1!x;\\$2$1!b
        s$1$1${4}$1
        s$1${6}$1${7}$1${9}
        s$1${10#-?}$1${11}$1${12#-?}
        "
++ sed '        1x;\d^.0d!{1!H;$!d
        };      \d^.0d{x;1!p;$!d;x
        };      \d^.0d!x;\d^.0d!b
        sdd&&&&d
        sd'\''dsqd4
        sd"d\dqdg
        '

এবং তাই lmatchকোনও ফাইলের শেষ ম্যাচের পরে ডেটাগুলিতে সহজেই রেজিজেস প্রয়োগ করতে ব্যবহার করা যেতে পারে। আমি উপরে যে কমান্ডটি চালিয়েছি তার ফলাফল:

5" 10' 15" 20'
25" 30' 35" 40'
45" 50' 55" 60'
65" 70' 75" 80'
85" 90' 95" 100'
101010105dq 110' 115dq 120'
125dq 130' 135dq 140sq
145dq 150' 155dq 160'
165dq 170' 175dq 180'
185dq 190' 195dq 200'

... যা, শেষ বারের /^.0/সাথে মিলিত হওয়া ফাইল ইনপুটটির উপসেটটি দেওয়া হলে নিম্নলিখিত বিকল্পগুলি প্রয়োগ করে:

  • sdd&&&&d- $matchনিজের সাথে 4 বার প্রতিস্থাপন করে।
  • sd'dsqd4 - শেষ ম্যাচ থেকে লাইন শুরু হওয়ার পরে চতুর্থ একক-উদ্ধৃতি।
  • sd"d\dqd2 - ডাইটো, তবে ডাবল-কোট এবং বিশ্বব্যাপী।

এবং তাই, lmatchকোনও ফাইলের মধ্যে শেষ কমা অপসারণ করতে কেউ কীভাবে ব্যবহার করতে পারে তা প্রদর্শনের জন্য:

printf "%d, %d %d, %d\n" $(seq 5 5 100) |
lmatch '/\(.*\),' -r\\1

আউটপুট:

5, 10 15, 20
25, 30 35, 40
45, 50 55, 60
65, 70 75, 80
85, 90 95 100

1
@ ডন_ক্রিসটি - এটি এখন আরও ভাল - আমি -mবিকল্পটি বাদ দিয়ে এটিকে বাধ্যতামূলক করে দিয়েছি , পুনরায় পুনর্নির্দেশের জন্য একাধিক যুক্তিতে স্যুইচ করেছি এবং -sযথাযথ বিস্ময়কর পরিচালনাও কার্যকর করেছি implemented আমি মনে করি এটি বুলেট প্রুফ আমি সীমাবদ্ধভাবে উভয় স্থান এবং একক উদ্ধৃতি সফলভাবে ব্যবহার করেছি,
মাইকসার্ভ

2

কমা যদি দ্বিতীয় থেকে শেষের লাইনে না থাকে

ব্যবহার awkএবং tac:

tac foo.csv | awk '/,$/ && !handled { sub(/,$/, ""); handled++ } {print}' | tac

awkকমান্ড প্রতিকল্পন প্রথমবার প্যাটার্ন দেখা যায় না একটি সহজ এক।  tacফাইলের মধ্যে লাইনের অর্ডার reverses, তাই awkমুছে ফেলার আপ কমান্ড প্রান্ত গত কমা।

আমাকে তা বলা হয়েছে

tac foo.csv | awk '/,$/ && !handled { sub(/,$/, ""); handled++ } {print}' > tmp && tac tmp

আরও দক্ষ হতে পারে।



1

দেখতে /programming/12390134/remove-comma-from-last-line

এটি আমার জন্য কাজ করা হয়েছে:

$cat input.txt
{"name": "secondary_ua","type":"STRING"},
{"name": "request_ip","type":"STRING"},
{"name": "cb","type":"STRING"},
$ sed '$s/,$//' < input.txt >output.txt
$cat output.txt
{"name": "secondary_ua","type":"STRING"},
{"name": "request_ip","type":"STRING"},
{"name": "cb","type":"STRING"}

আমার সেরা উপায় হ'ল শেষ লাইনটি সরিয়ে ফেলা এবং কমা অপসারণের পরে] আবার যুক্ত করুন


1

নীচে দিয়ে চেষ্টা করুন vi:

  vi "+:$-1s/\(,\)\(\_s*]\)/\2/e" "+:x" file

ব্যাখ্যা:

  • $-1 শেষ লাইন দ্বিতীয় থেকে নির্বাচন করুন

  • s প্রতিস্থাপন করা

  • \(,\)\(\_s*]\)একটি কমা অনুসরণ করুন ]এবং এর পরে স্পেস বা নিউলাইন দ্বারা পৃথক
  • \2\(\_s*]\)অর্থাত্ স্পেস বা নিউলাইন দ্বারা প্রতিস্থাপন]

-1

নীচের sedকমান্ড দিয়ে চেষ্টা করুন ।

sed -i '$s/,$//' foo.csv

1
এটি প্রতিটি লাইন থেকে ট্রেলিং কমা সরিয়ে ফেলবে , এটি ওপি চায় না।
আরকেমার

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