• 締切済み

cshの標準出力を制御したい

実は以下にも同じ質問があったのですが、回答がついてなかったので改めて質問させて頂きます。 cshで以下の様な形で"ls"の結果をシェル変数に取りたいのですが: set list = `ls *.s | sed -n 's/\.s//p'` lsの結果がマッチしなかったときに出力されるメッセージ: ls: 照合パターンに合いません. がコンソールに出力されると誤解を招くのでそれをやめさせたいのですが、何か良い方法はないでしょうか? 色々試しましたが簡単な方法は無い様な気がしています。 [コマンド] set list = `ls *.s | sed -n 's/\.s//p'` [例] (1) OKケース %>ls *.s aaa.s bbb.s 結果==> aaa bbb (2) NGケース %> ls *s ls: 照合パターンに合いません. [とりあえずやりたい事を実現する方法] ls *.s >& /dev/null if($status == 0) then # ls is matched set list = `ls *.s | sed -n 's/\.s//p'` endif ※ 冗長でかつ処理速度が遅いという問題があろうかと思います。 [以前の質問] http://www.okweb.ne.jp/kotaeru.php3?q=825419 以上宜しくお願いいたします。

みんなの回答

回答No.6

あれれ、ls|sedしてからSTDERRを/dev/nullに捨てるのは簡単でしたが、lsの時点で捨ててSTDOUTだけを引き渡すのは難しいですね!!自信ありだったのにすみません。 No.5で紹介されているリンク先では一発めに問題点としてあがっていますね。 私は大学時代にBSDを使っていてCシェルがメインでしたが、仕事やシステム管理をするようになってからはkshかbashを使っています(^^;

  • pawooon
  • ベストアンサー率25% (1/4)
回答No.5

こんな簡単なこともできないcshはプログラミングでは使うなといことですね。 どうしてものときは ( hoge.sh > /dev/tty ) > & /dev/null のようにシェル全体をやるしかないでしょう。

参考URL:
http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/
  • you-m
  • ベストアンサー率58% (190/327)
回答No.4

#1です。 手元の環境にて、以下のようなテストスクリプトを作成して実行しています。 ##------------ #!/bin/csh echo '## 1 File Exist ##' touch aaa.s bbb.s set list = `ls *.s | sed -n 's/\.s//p'` echo $list rm *.s echo '## 2 File Not Exist ##' set list = `ls *.s | sed -n 's/\.s//p'` echo $list touch aaa.s bbb.s echo '## 3 File Exist ##' set list = `(ls *.s | sed -n 's/\.s//p' > /dev/tty) >& /dev/null` echo $list rm *.s echo '## 4 File Not Exist ##' set list = `(ls *.s | sed -n 's/\.s//p' > /dev/tty) >& /dev/null` echo $list ##------------ 以下は実行結果です。 {134}# csh list_get.csh ## 1 File Exist ## aaa bbb ## 2 File Not Exist ## ls: No match. ## 3 File Exist ## aaa bbb ## 4 File Not Exist ## {135}# tcsh list_get.csh ## 1 File Exist ## aaa bbb ## 2 File Not Exist ## ls: 照合パターンに合いません. ## 3 File Exist ## aaa bbb ## 4 File Not Exist ## 環境は、FreeBSD2.2.8のcsh及びtcshにて確認しました。 あと、Cygwin上のtcshでも確認できています。 若干データの格納のされ方に違いがあるものの、きちんと取得は出来ていますし、一応の目的は達せられていると思います。 やっていることは決して特殊なことではないので、普通はこれで動くと思うんですが・・・

回答No.3

lsの結果がマッチしなかったときに出力されるメッセージは標準エラーに書かれます。cshの操作で、標準出力と標準エラーの振り分けの基本形は ( コマンド > 標準出力 ) >& 標準エラー これを応用するとNo.1でかかれているように、標準出力はTTYへ、エラーはブラックホールへ振り分けということができるわけです。

tk_1980024
質問者

お礼

有難うございます。 はい、基本形はその通りであると認識していますが、この標準出力のみを取り出すことが出来ずに困っています。試しに以下のようにして見てください。/dev/ttyへ取り出した出力はその後のパイプで取得が出来ていません。なぜならパタンマッチが行われていないからです。 [試行1] touch aaa.s bbb.s; ((ls *.s > /dev/tty) >& /dev/null) | sed -n "s/\.s//p" [試行2] touch aaa.s bbb.s; (ls *.s | sed -n "s/\.s//p") >& /dev/null ninja_ex250さんの通りの動作であれば結果は aaa bbb と期待されますが実際には aaa.s bbb.s あるいは <<blank>> となります。 以上引き続き宜しくお願いいたします。

  • pawooon
  • ベストアンサー率25% (1/4)
回答No.2

set list =`find . -name "*.s" -exec ls {} \; | sed -n 's/\.s//p'` でどうでしょう?

  • you-m
  • ベストアンサー率58% (190/327)
回答No.1

こんなやり方は如何でしょうか set list = `(ls *.s | sed -n 's/\.s//p' > /dev/tty) >& /dev/null`

tk_1980024
質問者

お礼

有難うございます。 ただこの方法では何もlistへ入ってきませんでした。 だめの様子です。。。

関連するQ&A

  • UNIXでフルパスのファイルリストを出力したい

    UNIXでフルパスのファイルリストを出力したいのですが、方法がわかりません。lsコマンドとfindコマンドを合わせればできるという記述がネットにあったのですが、詳細がなかったためわかりませんでした。 すいませんが、ご教示ください。 フルパスの出力結果例 d:\aaa\bbb\ccc.html

  • ファイル中の数行を抜き出す処理について(シェル)

    ファイルaaa.txtの2行目から4行目を抜き出し、 ファイルbbb.txtに格納する方法として、 sed -n '2,4p' aaa.txt > bbb.txt がありますが、 変数を使用し、 start=2 end=4 sed -n '${start},${end}p' aaa.txt > bbb.txt とすると、エラーが発生します。 どうすればよろしいのでしょうか。

  • SEDの使い方

    こんにちは。 sedである複数行のパターンにマッチしたら置き換えるということをしたいのですが上手くいきません。 たとえば、 test.txt aaa bbb ccc に対して、 sed -i.bak s/aaa/aaa'\n'111/g test とすると、 test.txt aaa 111 bbb ccc となります。 これを戻す方法として、 sed -i.bak s/aaa'\n'111/aaa/g test としても、元に戻りません。 sedを用いで元に戻す方法をご教示いただけないでしょうか。 よろしくお願い致します。

  • tail -f の出力に|(パイプ)を2回

    tail -f の出力への|(パイプ)を2回行ったものの結果が出力されず困っています。 具体的には、下記のようなコマンドを実行しています。 tail -f hoge.txt | sed -e 's/aaaa//g' | grep 'moge' 2個目のsedのみにすれば問題なく出力されるのですが、最後のgrepを行うと何も出力されなくなってしまいます。(sedの結果がgrepに渡れば必ず出力されるはずのもの) |(パイプ)の仕組みの理解が曖昧な気がしているのですが、なぜこうなってしまうのかがわかる方がいらっしゃれば教えてください。

  • sedでカンマ区切りの列の置換を行いたい

    以下の様なファイルがあります。 sedコマンドを使用して、カンマで区切られたn番目のカラム目を 置換したい場合どうすればよいでしょうか。 "1","2","3","4","5","6" "1234","12","34567","abcd","efg","hi" "a c","d f","12 34","0","AAA","" "g i","j l","45 67","0","BBB","2021" "m o","p r","3 2 1","1","ABC","" "123","456","","abc","efg","hij" ①1カラム目以外置換(1カラム目以降削除) sed 's/\(.*\),.*,.*,.*,.*,.*/\1/g' test.csv ②最後の6カラム目以外置換(6カラム目以外削除) sed 's/.*,.*,.*,.*,.*,\(.*\)/\1/g' test.csv ③3カラム目を置換(3カラム目を「""」だけにしたい) sed -e 's/\(.*\),\(.*\),.*,\(.*\),\(.*\),\(.*\)/\1,\2,"",\3,\4,\5/g' test.csv とできたのですが、 表現がないというか、置換対象文字列の条件、表現が長いというか、全カラムを指定しているので、 少し、短くできないものでしょうか。 ①パターン sed 's/\([^,]*\),.*/\1/g' test.csv ②パターン sed "s/.*,\([^,]*\)$/\1/g" test.csv の様にできました。 ③パターン 思いう浮かばず これで、できているので間違いはないかとおもいますが、 どうなのでしょうか。 なにかいい案はないでしょうか?

  • テキスト検索にヒットした行の次を出力したい

    あるコマンドを実行するとホスト名とそのステータスが2行にわたって得られるものがあります。 例えば以下のような結果になります。  Host = aaa  Status = 2  Host = bbb  Status = 1  Host = 123  Status = 5    : ここで、Host = bbbに該当する「Status = 1」の情報だけ抜き取る方法を考えています。 プログラミング能力のない自分では、  実行結果をファイルに書き出してperlでHost = bbbの該当行まで読み飛ばして次の行をprintで出力する という方法しか考えつきません。 awk,sed,perl,rubyなんかでワンライナーで実行できたらいいなぁと思っているのですが、 環境はLinuxまたはcygwinです。 何かいいアドバイスをお願い致します。

  • cshからperlを呼び出しファイルに出力

    いつもお世話になっております。 cshからperlを呼び出しperlが出力する内容と入力項目を実行しているcsh内部で行ない結果をファイルへ出力したいのですが、そのような事ができるのでしょうか? ---------- cshファイル内 #!/bin/csh echo "●perl a.pl を実行します" | tee a.log perl a.pl ---------- perlファイル内 (perlがわかりませんので、perlの内容をcsh形式で記述させていただきます) (1)echo -n "日付を入力して下さい" (2)echo "⇒ " (3)set INPUT_DATE = $< (4)echo "日付:$INPUT_DATE " exit 0 ---------- cshから実行されたperl(csh)の内容[(1)(2)(3)(4)]をファイル(| tee a.log)へ出力することが可能でしょうか? ご存知の方がいらっしゃいましたらご教授願います。

  • 標準出力と標準エラー出力を変数にセットしたいです。

    始めたばかりの初心者の為、変な質問でしたら申し訳ありません。 標準出力と標準出力を別々の変数にセットしたいのですが、そのやり方が分からず困っています。 やりたいことは、 コマンド(diffやcatなどの)実行結果の標準出力と標準エラー出力を それぞれ「任意の文字_受取パラメータの値」にセットすることをしたいです。 下記は、1回ファイルに出力して、それを読んで変数にセットするように記述したものです。 ※記述間違っていたらすみません。 ファイルに書かなくても、パイプやその他コマンドなどで出来る方法はないでしょうか? ex) test.sh 1.txt 2.txt TEST01 で実行 #!/bin/sh parm1 = $1 parm2 = $2 parm3 = $3 diff "${parm1}" "${parm2}" > test.log 2> err.log eval w_stdout_${parm3}=¥`cat test.log¥` eval w_stderr_${parm3}=¥`cat err.log¥` eval echo "stdout:¥"¥{w_stdout_${parm3}}¥"" eval echo "stderr:¥"¥{w_stderr_${parm3}}¥"" ※実行した結果 stdout:diff結果 stderr:空白 お手数ですが、何卒宜しくお願い致します。

  • 「照合パターンに合いません」の回避法

    ディレクトリ/test内のファイルをリストアップして 配列に格納するためにcshスクリプトにて set LIST=( /test/* ) とすると、ディレクトリが空の場合 setコマンドが「照合パターンに合いません」 というエラーを吐きます。このエラーが起きると シェルスクリプト内で返値を拾ってエラー対処することも できず、スクリプトが落ちます。これを何とか回避する 方法はないでしょうか? 前もってlsやfindでディレクトリの中身が空でないことを 調べるというのは却下です。

  • 多数あるファイル(text base)の*行目だけを引っ張ってきて標準出力させたい。

    Unix初心者です。 SunOS > head -1 ./*.txt とすれば、以下のように1行目だけを引っ張ってきて標準出力させる事も可能ですが。 ==> 1234.txt <== hello ==> 1235.txt <== hello SunOS > head -2 ./*.txt とすると、1行目と2行目が標準出力されます。 ==> 1234.txt <== hello bye ==> 1235.txt <== hello bye ですが、以下に例をあげますが、このように " 2行目だけ " を標準出力させたいのです。 ==> 1234.txt <== bye ==> 1235.txt <== bye sed -n '2p' ./*.txt だと、理由は不明ですが一つのファイルしか標準出力されませんでした。 head 、sed でなくともawk grepでも構いません。 その他の自分の知らないコマンドで構いません。 文字検索ではなく、*行目と行数指定です。 できれば、ファイル名も同時に出力させたいのです。 欲を言えば、行数も出力させたいです。 更に、翌を言えば、指定行を増やせたら最高です。 例;)1行目と3行目を標準出力する。 scriptを作りこまずに、|(パイプ)でつなげれば一行のコマンドで処理可能なのでは ないかと想像してますが、いかがでしょうか。 宜しく頼みます。