シェルスクリプト総合 ..
116:login:Penguin
07/09/07 17:39:52 aiZtBudz
>>115
もう一回自分で書いてみたら?
117:login:Penguin
07/09/07 19:24:55 Txvf/Wl4
find /data -mindepth 1 -maxdepth 1 -type d -exec ...
shopt -s nullglob
for i in /data/{,.{[!.],.?}}*/
do ...
こんなんでいかが
118:login:Penguin
07/09/07 19:45:52 ezpNZgi5
cat hoge | awk
に似ている。
119:login:Penguin
07/09/07 20:30:25 BZSReuYl
>>116
OK。これでどうだ?
find /home/* -maxdepth 0 -type d
120:login:Penguin
07/09/08 04:46:18 WlyFgm6n
>>117 でもう答え出てるじゃん。
>>119
/home/.xxx/ とかが出ない。
* 使うなら find 使う意味ない。
121:login:Penguin
07/09/08 14:42:47 vllGfkN4
>120
>* 使うなら find 使う意味ない。
上下別々の回答なんじゃないの?
122:login:Penguin
07/09/11 03:08:21 997sWGjJ
bashrc の書き方もこのスレでいいですか?
123:login:Penguin
07/09/12 11:40:47 EatE1MlG
#!/bin/sh -f
ls *.dat > list.txt
なぜか走らん。
124:login:Penguin
07/09/12 17:16:53 A49nKXNq
>>123
子プロセスとして(?)起動するシェルに -f が渡らないんだと思う。
/bin/sh -f hoge.sh とか
あらかじめ /bin/sh -f で起動したシェルで
./hoge.sh みたいにすると
-f が有効になる。
125:login:Penguin
07/09/12 17:21:21 EatE1MlG
>>124
エラーで *.dat: ファイルもディレクトリもありません とでる
ワイルドカードが原因かと思ったけど、hoge*でも同様のエラー
シェルにしたら走らず、コマンドラインで直接投げたら走る
なんでだろ
126:124
07/09/12 17:27:12 A49nKXNq
>>125
/bin/sh -f の -f がどんな意味かわかってる?
あと、シェルとシェルスクリプトはちゃんと区別したほうがいい。
127:login:Penguin
07/09/12 17:33:44 EatE1MlG
!/bin/cshで走ったわ
コンソールがcshだった
128:login:Penguin
07/09/12 20:01:20 9HkBr7tD
複数のpasswdファイル(passwd_A、passwd_B)を結合して、同じユーザ名があった場合
passwd_Aのものだけを残すというようなことをしたいのですがどうすればよいでしょうか?
129:login:Penguin
07/09/12 20:12:55 nfcPR4Gc
いったんファイルを結合する
一行ずつ上から順に読んでパスワードファイルに書き込む
書き込んだらそのユーザー名を別ファイルに書き出す
その別ファイルにユーザー名がないことを確認してから
パスワードファイルに書き込めばよい
130:login:Penguin
07/09/12 22:19:22 qqfxe9V8
while read t ;do
if [ "`grep ^${t%%:*}: passwd_A`" ];then
continue
else
echo $t >>passwd_A
fi
done <passwd_B
131:login:Penguin
07/09/12 22:53:21 SML918nz
んだば awk で。
awk -F: '{
t[$1] = $0;
}
END {
for (e in t)
print t[e];
}' passwd_B passwd_A
132:login:Penguin
07/09/12 23:49:46 lhLTsTba
awk -F: '!($1 in t){print;t[$1]=1;}' passwd_A passwd_B
133:login:Penguin
07/09/13 21:53:28 8j1+julM
aaa.txtの中身
20070109,170000,170000,167000,170000,4
20070110,168000,168000,168000,168000,10
20070115,171000,171000,163000,169000,500
を
2007/01/09,170000,170000,167000,170000
2007/01/10,168000,168000,168000,168000
2007/01/15,171000,171000,163000,169000
のように
YYYY/MM/DDと表示を変更する
最後の,からあとを削除してbbb.txtとして出力したいと思っています
どのようにすればいいものでしょうか
4文字目と5文字目の間に/を挿入するということがsedでできなくて悩んでおります
よろしくお願いいたします
134:login:Penguin
07/09/13 22:06:02 OVx1tSlg
cat /tmp/aaa.txt | gawk -F, '{printf("%04d/%02d/%02d,%s,%s,%s,%s\n", substr($0,1,4),substr($0,5,2),substr($0,7,2),$2,$3,$4,$5)}' > bbb.txt
135:login:Penguin
07/09/13 22:08:03 G9V8Phhb
\(\)でグルーピング、\{\}でマッチする回数の指定。
グルーピングしたパターンは後で\1,\2で参照出来る。
\を忘れるなよ。
136:login:Penguin
07/09/13 22:09:20 G9V8Phhb
あ、ごめん、>135はGNU sedの話
137:login:Penguin
07/09/13 22:25:32 8j1+julM
>>134
ありがとうございます
gwakというのも勉強してみようと思います
138:login:Penguin
07/09/13 22:52:13 8j1+julM
>>134
manを見てみたら いろんなところで使用できそうです
本当にありがとう
139:login:Penguin
07/09/13 23:24:02 saILvvtf
>>134
catは要らんだろ。
140:login:Penguin
07/09/14 00:50:00 uh85VpLs
正規表現も勉強した方がよろしいかと>>138
141:login:Penguin
07/09/14 12:28:52 hH9EcwDJ
ある XXX っていう名前を含んだプロセスを全て殺したい時、
ps aux | grep XXX | grep -v grep | awk '{print $2}' | kill
ではだめなのに
ps aux | grep XXX | grep -v grep | awk '{print $2}' | xargs kill
ではOKなのはなぜですか?
142:login:Penguin
07/09/14 12:34:24 18sjQ9F0
>>141
kill って標準入力を受け付けないんじゃない。
ところで pkill XXX じゃだめなの?
143:login:Penguin
07/09/14 12:37:30 hH9EcwDJ
>>142
そうなのかなと思って
for p in $(ps aux | grep XXX | grep -v grep | awk '{print $2}'); do
kill "$p"
done
ってのもやってみたんですが、だめだったんですよ。
144:login:Penguin
07/09/14 17:32:35 Ney/3ygS
スクリプトでタイマー作れませんか?
一定間隔ごとに単純にコマンド出すだけじゃなくて
処理ごとに条件分岐してタイマーを止めたりコマンドが成功
するまで繰り返したりしたいのですが
145:login:Penguin
07/09/14 20:21:33 KxObz0sB
>>144
sleep使って、て程度で良いなら作れるような気しかしないんだけど、具体的にどうしたいのか書いたのが良いと思うぞ。
146:login:Penguin
07/09/14 20:32:43 RM0kquC+
>>144
どこまで出来たの?
147:login:Penguin
07/09/14 23:57:41 XHXILi6a
>>143
だめってどうダメだったのかわからんと。
for p in $(ps aux | grep smbd | grep -v grep | awk '{print $2}'); do
"kill "$p"
done
これでやったらちゃんと動いたよ。スクリプトの問題じゃなくて
単に権限がなくてkillできなかっただけでは?
148:login:Penguin
07/09/15 16:55:13 /cIKvz/T
>>147
さっきやってみたら出来た。。。
間違って mplayer を40個くらい起動してしまって、そこでそのスクリプトを
叩いたつもりだったんだけど、焦ってなんか間違ってたのかもしれない。
とりあえず今度からは xargs のほうを使うようにするよ。
149:login:Penguin
07/09/15 17:28:32 YiwEKkpX
いやだからpkill使えって
150:login:Penguin
07/09/15 17:49:23 X+i1f7J3
command | command みたいな
例
cat hoge.txt | grep piyo
書き方があるじゃないですか? cat hoge.txt で出力される標準出力をパイプかませて
その出力内容に対して grep piyo をかける と言うような。
これと
xargs ってコマンドがあるじゃないですか?その違いがよく分からないのですが・・。
cat hoge.txt | xargs grep piyo
みたいな?
151:login:Penguin
07/09/15 18:13:14 YiwEKkpX
「cat hoge.txt | xargs grep piyo」=「grep piyo `cat hoge.txt`」
152:login:Penguin
07/09/15 18:42:58 X+i1f7J3
>>151
ほぉほぉ・・・・
cat hoge.txt | xargs grep piyo が
grep piyo `cat hoge.txt`
と同じならば
cat hoge.txt | grep piyo
は
grep piyo hoge.txt
ん?なんか混乱してきた・・・イマイチはっきりと分からない・・・
153:login:Penguin
07/09/15 19:03:27 8eNJORpc
argっていうぐらいだから引数に展開してくれるのだろ
その場合hoge.txtの中身はファイル名でないとだめ
154:login:Penguin
07/09/15 19:15:07 jJyNjt7I
もう分かってるかもしれないけど、xargsは標準入力をコマンドライン引数に変換するだけ。
echo 'file1 file2 hoge' | xargs rm
↓
rm file1 file2 hoge
155:login:Penguin
07/09/15 19:47:59 X+i1f7J3
むぅ・・・
echo `file1 file2 hoge` | xargs rm
が
rm file1 file2 hoge
となるならば
echo `file1 file2 hoge` | rm
は
どう展開されるんですか? すみません、ほんと頭弱くて。
156:login:Penguin
07/09/15 19:51:39 YiwEKkpX
引数と標準入出力の区別がまだついてなくて、全部「入力」として
ごちゃまぜの段階でしょ?まずそれを考えてみるんだ>155
157:login:Penguin
07/09/15 23:18:03 +DsxitZ3
>>154の echo 'file1 file2 hoge' | xargs rm
>>155の echo `file1 file2 hoge` | xargs rm
どこが違うか理解してからにしろ
158:login:Penguin
07/09/15 23:25:38 PpA5ThvC
こんな初歩の初歩みたいなことに、どうしてそんなに高飛車になれるんだ。
159:login:Penguin
07/09/16 01:01:56 S5o7UTSR
初歩の初歩は自力で身に付けてから来てくれよ。
160:login:Penguin
07/09/16 01:06:18 BSYCrrV+
タコタコ
161:login:Penguin
07/09/17 04:16:34 nqz563FT
convmv -r -f sjis -t utf-8 * --notest
で、再帰的にカレントディレクトリ以下のファイル、ディレクトリ全てに対して
sjisからutf-8に変換をかけるコマンドを打ったのですが、sjisとeuc-jpが混在していて
convmvの仕様だと 1ファイルでも -f で指定した文字コード以外の文字コードのファイルが
存在した場合はそこで全ての変換処理が実行されなくなってしまいます。
違う文字コードの場合は除外して残りを全て処理してくれるオプションは無いかとman convmv
を読んで見ましたが、無いようです。
仕方が無いので、これをシェルスクリプトで実現したいと思います。
実際にやりたいコマンドは
convmv -r -f sjis -t utf-8 /data/* --notest で、これで変換できないファイルは
convmv -r -f euc-jp -t utf-8 /data/* --notest で、全てのeuc-jpとsjisをutf-8にする事です。
for TARG in `find /data | nkf -w8`
do
convmv -f sjis -t utf-8 ${TARG} --notest
convmv -f euc-jp -t utf-8 ${TARG} --notest
done
これで、sjisのファイルだろうがeuc-jpのファイルだろうが必ずutf-8になると思われますが
いけると思いますか? | nkf -w8 をかませているのは、こうしないとターミナルで見た限りだと
文字化けしたファイル名でそのまま表示されるので、これだと多分ファイルにアクセスできないだろう
との配慮から、ちゃんとしたファイル名で見えるようにしたつもりです。
162:login:Penguin
07/09/17 08:49:52 hnYIly1T
>>161
qkc最強伝説
163:login:Penguin
07/09/17 11:57:35 nqz563FT
>>162
URLリンク(hp.vector.co.jp)
これですよね?
しかしこれはconvmvとは全く別物のようです。
convmv => ファイル"名"の文字コードを変換する ←私はコレが必要
qkc => テキストファイルの"中身"の文字コードを変換する ←これは違う・・・
なので使えないみたいです。
ちなみに >>161で書いたスクリプトを実際に動かしてみた所、LinuxサーバのCPU使用率が
100%になって固まっちゃいました。無限ループをしているかファイル名取得に失敗しているか
よく分かりませんがダメでしたOTL
164:login:Penguin
07/09/17 12:18:44 CDwJTqgj
よくわからんのだが、nkf -gで文字コードの判別してやりゃ良いんじゃねぇの?
165:login:Penguin
07/09/17 12:56:16 RA5G8Fdp
while ! convmv -f sjis -t utf-8 -r /data --notest ; do
convmv -f euc-jp -t utf-8 -r /data --notest
done
なんか、どうよ?
文字コード判定がいまいちなのか誤認してくれたりするので --notest とって、ざっと眺めてからやる事を推奨。
166:login:Penguin
07/09/17 13:00:08 85s13mgP
--notest 外して試してみればーじゃん。
167:login:Penguin
07/09/17 13:21:00 hplwR1nR
echo $RANDOM
で結果に乱数を返したいんですけど、
0〜9までの一桁の結果のみ返したい場合の指定方法とかってありますか?
168:login:Penguin
07/09/17 13:53:15 MlIRuyKv
$RANDOM % 10
169:login:Penguin
07/09/17 15:09:07 nqz563FT
>>164
nkf はファイル"名"ではなくて、ファイルの"中身"についての文字コードを
調べるんですよね?テキストファイルに対して実行するとShift-JISと言う出力が得られ、
.exeファイル等に実行すると Binary と表示されました。
なので、これは全く別物です。
>>165
おお・・・
それはつまり
convmv -f sjis -t utf-8 -r /data --notest
で、元ファイルがsjisじゃなかったときは元ファイルがeuc-jpとして処理を繰り返すんですね。
しかしその場合、仮に1つでも元ファイルがsjisだった場合は?と言うか・・・
それ実行してみたのですが、無限ループに陥りました。何度も同じファイルを判定して
これsjisじゃないよ〜って帰ってきます。
よくよく考えると -r /data で既に再帰的に繰り返す処理なのに、それをさらにwhileでループさせて
いるんですよね。二重ループ状態ですか。
while ! convmv -f sjis -t utf-8 -r /data --notest ; do
これで、とりあえず convmv -f sjis -t utf-8 -r /data --notest が実行される
→実行された時に1つでも違うファイルが存在していてエラー
→convmv -f euc-jp -t utf-8 -r /data --notest が実行される
→実行された時に1つでも違うファイルが存在していてエラー
またconvmv -f sjis -t utf-8 -r /data --notest が、最初にエラーで止まったファイルも含んで
最初から実行される>当然また同じファイルでエラーを起こす>convmv -f euc-jp -t utf-8 -r /data --notest が
また実行されてまたこれも最初から処理してしまう>これを永遠に繰り返して無限ループに陥る。
ダメみたいですOTL
>>166
--notestはずして試してみてますが、エラーで弾かれます。
170:login:Penguin
07/09/17 15:30:26 kUn2DAgf
>>169
いや、ファイル名のコードをnkfで調べりゃいいじゃん、てことだったんだけど。
171:login:Penguin
07/09/17 15:35:55 kUn2DAgf
念のため。
for T in `ls ~`
do
C=`echo "$T" | nkf -g`
echo $T,$C
done
ファイル名の文字コードを調べてると思うんだが。
172:login:Penguin
07/09/17 16:38:42 nqz563FT
>>170-171
違うと思うなぁ・・・。
>>171のスクリプト実行してみたけど
これは ls ~ で表示されるファイル名リスト全体、、、そうだなぁ、、例えば
a.txt
b.mp3
c.tar
d.gz
e.tar.gz
とか日本語も含むファイル名全てが列挙されると思うけど、それらのファイル名リスト
全体を1つのテキストファイルとみなして、テキストファイルの中身(つまりファイル名が列挙されてる)
に対して文字コード変換をかけた結果を echo で出力しているんじゃないですか?
だからnkf は ファイル"名"の文字コードを調べるんじゃなくて、あくまでもテキストファイルの中身
の文字コードを調べるんだと思いますが。それこそqkcみたいな動作?
convmvは全くそれとは性格が異なる物だと思いますが、、非常にこの辺ややこしい・・・。
173:login:Penguin
07/09/17 16:45:55 8vN1DPCo
なんでこんなに全然わかってないのに自信満々なのだろうか
174:login:Penguin
07/09/17 16:47:06 rlyHM/pf
>>161
>>164 の意見を採用して書いてみた。
for を while に変えたのは俺の趣味。
find /data | while read TARG ; do
File=$( nkf -g <<< "$TARG" )
case "$File" in
Shift_JIS*) Code=sjis ;;
EUC-JP*) Code=euc-jp ;;
UTF-8*) continue ;;
esac
echo "$File: Convert to $Code" ## お好みで
convmv -f "$Code" -t utf-8 "$TARG" --notest
done
ファイル名程度の短い文字列だと nkf の文字コード判定の
精度はあまりよくないが、やらないよりはマシだろう。
175:login:Penguin
07/09/17 16:52:30 HxbR0j5A
文字コードが違うファイル名が混在しているディレクトリって。
どうしてそうなったかが気になる
176:login:Penguin
07/09/17 16:55:54 4XOwAbVo
ローカルで作ってSambaで作ってWebDAVあたりで作ってとやってしまうと
起きるな?>混在。
後はデータ中の文字列を元にファイルを作ったりすると、うっかり
混在状態になったり。
177:login:Penguin
07/09/17 17:22:02 kUn2DAgf
>>172
>>173と同意なんだが、想像の斜め上な方向に理解してるのね。と理解。
なして>>171を実行してみた上で>>172になるのかわからん。。。
つまり、>>172としては、「a.txt あ.txt い.txt」の3つのファイルがあると、
a.txt, ASCII
あ.txt,UTF-8(とか)
い.txt,EUC-JP(とか)
てならず、
a.txt,BINARY
あ.txt,BINARY
い.txt,BINARY
となった、てこと?
>>174
半角カナ使ってなけりゃ、それなりの精度なんじゃねぇかと思うんだけど、どうだろ。
178:login:Penguin
07/09/17 17:29:26 kUn2DAgf
>半角カナ使ってなけりゃ、〜
↑勘違い。すま。
179:login:Penguin
07/09/17 19:31:50 nqz563FT
>>173
すみませんOTL。
>>174
そのスクリプト動かしてみたのたですが、 echo ${File}を加えて確認した所
ほとんどのファイルが ASCII と出力されていて、少しだけ Shift-JISという出力が得られました。
って事は?Shift-JISとASCIIが混在しているという事でしょうか?
と言うかそもそもASCIIっていったいどういう・・?
euc-jp sjis utf-8 の3種類しか基本的には知らなくていいと思っていたのですが、4つ目の文字コード
も混在している(というよりeuc-jpのファイルは存在しなくてsjisとASCIIの2つが混在?)と言う事でしょうか。
と言うか convmv --list してみたら asciiってあるし・・・・。
>>176
そうそう、さらにFTPも混ざったりssh + rsyncとかでファイル持ってきたりすると
もう今ぐちゃぐちゃになってて、UTF-8に統一したいんですよ。。。
>>177
.txtの拡張子のファイルは BINARYはでません。
ん?って事は nkf -g ではファイル"名"の文字コードを判別しているって事ですか?
で、その出力がASCIIとShift-JIS、その他としてはBINARYの3種類の状態(だと思う)の場合は
convmv -f ascii -t utf-8
convmv -f sjis -t utf-8
でそれぞれ変換かければいいのかな・・・。なんか難しすぎて頭痛くなってきたOTL。
でもなんか全面的に私が間違っていた感じがするので、その点については皆様方には
大変ご迷惑をお掛けしておりまして申し訳ありません。
180:login:Penguin
07/09/17 20:51:38 kUn2DAgf
>>179
なんていうか、なぁ。
ASCIIってのは日本語使ってなけりゃASCIIだわな。ちと語弊あるけど。「a.txt」とか。
で、オレの>>177で示したのは、>>174をオレ解釈したところ、
「a.txt」と「(UTF-8な)あ.txt」と「(EUC-JPな)い.txt」が混在してると、いっしょくたになったのが
コード判別にかかって、結局コード判別できなくって「BINARY」って判別されるってことか? と。
オレの説明わかり難かったとは思うけどな。
でもってnkf -gだが、たんに「入力された」のの文字コード体系を調べるだけであって、それが
「ファイルの中身」なのか「ファイル名」なのかは、どっちを指定、てか、nkfに入力したか、て
違いだけ。わかる?
ついでに日本語のファイル名がShift-JISだけなら、SJIS→UTF8に変換指定するだけでokやな。
そんなわけで、まちっと勉強しれ。
181:login:Penguin
07/09/17 21:22:34 rlyHM/pf
>>179
ああ、そういや ASCII を忘れてた。w
解説は >>180 を見てもらうとして、
それを踏まえて >>174 を改良すると、こんな感じかな。
後は自分で調べてみな。
find /data | while read TARG ; do
File=$( nkf -g <<< "$TARG" )
case "$File" in
Shift_JIS*) Code='sjis' ;;
EUC-JP*) Code='euc-jp' ;;
ISO-2022-JP*) Code='iso-2022-jp' ;;
ASCII*|UTF-8*) echo "$TARG: $File"; continue ;;
*) echo "$TARG: $File: Not supported format."; continue ;;
esac
echo "$File: Convert from $Code to UTF-8." ## お好みで
convmv -f "$Code" -t utf-8 "$TARG" --notest
done
>>180
> 「a.txt」と「(UTF-8な)あ.txt」と「(EUC-JPな)い.txt」が混在してると
判定はファイルごとに行うからこれで「BINARY」にはならないはず。
「(UTF-8)あ(EUC-JP)い.txt」とか、複数の文字コードで構成された
ファイル名だと誤判定と言うか、期待通りにはならないと思う。
こういうのもきちんと判定したいのなら ack がお勧め。
こんなファイル名に出くわす事はまずないだろうけどな。w
182:login:Penguin
07/09/17 22:20:42 nqz563FT
>>180
なるほど、英数字だけの場合はASCIIなんですね・・。
では、 a.txt(ASCIIですよね) を convmv -f ascii -t utf-8 a.txt --notest
なんて有り得ないわけですよねぇ。
BINARYって判別されたのは 例えば vncviewer.exe とかのファイルです。バイナリファイルだし。。。
この結果を見て私は vncviewer.exe と言うファイル名自体は英数字のみなので ASCIIかと
思いますが、しかしvncviewer.exeのファイルの"中身"はBINARYなので、nkf ってのは
ファイルの中身を見てコードを判別して返してくれるんだなぁと思った次第です。
(nkf がファイル"名"を見て返してくれるのなら vncviewer.exeはBINARYではなくASCIIで
かえって来ないといけないからです。) でも nkf に対して何を入力するかによって
返してくるものは違うんですね。ファイル"名"をnkfに入力すればファイル"名"のコードが帰ってくるし
ファイルの内容を入力すればファイルの内容のコードが帰ってくると。
>>181
度々具体的なスクリプトを示して頂いて本当にありがとうございます。
しかしですね・・・よくエラーを見てみると no such file or directory が帰ってきてるんですよね・・・。
つまり find /data をした結果、文字化けしたファイル名が返ってくるわけじゃないですか。
その文字化けしたファイル名の場合、そのファイルにはアクセスする事が出来ないですよね。
文字化けしたファイルに唯一アクセスする手段があるとすれば、それは "*" を使う事ですよね。
だから for や while で1ファイルずつ処理するっていう最初のアイディア自体がそもそも不可能
だったと言う事に今更ながら気づきました。ほんと文字化け問題って大変ですね・・。
"*"を使うと言っても find /data/* だと結局1ファイルずつ文字化けしたものが帰ってくるので
ダメっぽいです。 convmv に 直接 * を渡す必要があるみたいで、そうすると混在している場合に
全く処理をしてくれなくて結局ダメと。。。参ったなぁ・・・OTL。
それと1つシェルスクリプトスレなのでお聞きしておきたいのですが
File=$( nkf -g <<< "$TARG" ) ←これなんですが、 <<< って何ですか?普通 < か << ですよね。
<<<は初めて
183:165
07/09/17 22:30:38 RA5G8Fdp
>>169
エラーの起こる直前までは変換してくれるのかと思ってた。
いらぬ時間をとらせてすまねぇ。
んで(w)、また懲りずに考えてみたんだが、nkf使うんだったら
find work/ -type f -exec sh -c 'FN="`dirname \"{}\"`"/"`basename \"{}\" | nkf -w`"; [ -f "$FN" ] || mv -v "`echo \"{}\"`" "$FN"' \;
とかいかが?
ディレクトリ含まれてないんだけど、含むと末端からやらないといけないからシェルスクリプトでやるのは面倒くさそうだなァ、と思って逃げたw
184:login:Penguin
07/09/17 23:04:07 nqz563FT
>>183
うぐぅ・・・・
そのfind 以下のスクリプト難しすぎて私には何をどうしているのかさっぱり分かりませんです。。
awkとか正規表現とかそこら辺全然知らないので、なんかそれっぽいコードに見えて読めないOTL。
ディレクトリを含まないって言うのも問題ですねぇ・・・。
例えばですが hoge.txt と piyo/ っていうディレクトリが存在していて、それぞれのファイル名
もしくはディレクトリ名の文字コードを知りたい場合はnkfではどのようにコマンド入力したらいいんですか?
ls -d piyo/ | nkf -g
nkf -g < hoge.txt
nkf -g | `ls -d piyo/`
nkf -g <<< hoge.txt
等など色々試してみましたが、文字コードが見えませんでした。
# convmv ももう少し気を利かせて --force オプションなんて作ってくれて処理できないファイルは
スキップして処理可能なファイルだけ全部処理するみたいな機能盛り込んでくれてれば助かったんだけどなぁ・・・。
185:login:Penguin
07/09/17 23:10:07 kLzbccVO
無理してシェルで書くより
perl かなんかで書いちゃった方が早い気がする。
186:login:Penguin
07/09/17 23:26:23 hplwR1nR
すいません、いろいろやってみたけど出来ないので教えてください。
aaaa,bbbb,cccc,"hoge,hoge",ddd,eee,ffff
みたいなCSVが有ります。
※カンマがある列は必ず「""」で括られています。
# cut -d, -f 4
とかでカンマが含まれる行を出力しようとすると 結果に「"hoge」とのみ出力されてしまいます。
本当は「"hoge,hoge"」が出力されてほしいのです。
「"hoge,hoge"」の出力結果を得るためにはどの様にすれば良いですか?
自分的には、
sedコマンドでいったんワークファイルwor.csvなどに「"hoge\,hoge"」と
エスケープシーケンスを追加してからcutコマンドを実行すればうまく行くような気がしているのですが、
sedをどのように記述して良いのかすら解りません(泣)
どなたか教えてください。。。。
187:login:Penguin
07/09/17 23:42:08 kUn2DAgf
実は混在なんかしてない、ていうことはないのんか? もしくはかなり偏っている。
なら、ある程度手作業でその他一括、のが楽かも知れん。
188:login:Penguin
07/09/17 23:45:48 msAJx7Dr
結局カンマ関係なしに""で括られたのが欲しいんじゃねぇのか?
189:login:Penguin
07/09/18 00:04:13 hplwR1nR
186です。
>>187
1000行近くのCSVファイルで確実に混在しています。
例えば、↓↓↓みたいな行です。
(「US」の後ろにカンマがありますよね?)
75,0,,,-,,-,"LOG3\.0.*123456 .....5.*\(US, 21\): NOTICE:.*",,,,,,,AAAA,BBB,"TEST",WARN,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,,,,,,,,,,,,,,,,,,,75
この行から特定の列だけ抜き出し&抜き出しした列を引数にコマンドを実行しています。
>>188
そんなことないです。
実際には初期値の列も多いので。
190:login:Penguin
07/09/18 00:16:17 u/C4qzX6
>>182
read に -r オプションつけたらどう?
旧) find /data | while read TARG ; do
新) find /data | while read -r TARG ; do
^^^
> File=$( nkf -g <<< "$TARG" ) ←これなんですが
man bash のヒア・ストリングス (Here Strings) の項を参照。
191:login:Penguin
07/09/18 00:35:05 u/C4qzX6
>>189
う〜ん、難しいね。
クォートされたエントリが一行に一つだけなら
↓で取り出すことはできるけど。
sed '/"/ s/.*\(".*"\).*/\1/'
俺なら一度 csv を Excel に放り込んでから
特定の列を抜き出すかな。w
192:login:Penguin
07/09/18 02:15:13 AGCqK3mV
sed -n 's/\(\("[^"]*"\)\|\([^,]*\)\)\(,\|$\)/\n\1\n/4;s/[^\n]*\n//;P'
sedでやってみた。
193:login:Penguin
07/09/18 07:39:01 +nqx9VGy
186です。
ありがとうございます。
191,192を実行してみたんですけど、正しく表示されませんでした(泣)
194:login:Penguin
07/09/18 12:30:11 Gq30BMp3
>>186
センス悪いけどこんなのでよければ
#!/usr/bin/gawk -f
BEGIN{n=ARGV[1];ARGV[1]=""}
function parse(s,c,f,i,j,k){
while(1){c=substr(s,i,1);if(c=="")return;else if(c=="\"")f=(f>0)?0:1
else if(c==","&&f==0){array[k++]=substr(s,j,i-j);j=i+1}i++;}}
{parse($0);print array[n]}
195:192
07/09/18 18:40:20 AGCqK3mV
/^o^\懽ッ懽懽懽セ懽」懽セ懽
自分の環境では、186と189は上手くいってるぽいんだが。
例えば、189は192の4の所を8にすれば
"LOG3\.0.*123456 .....5.*\(US, 21\): NOTICE:.*"
って出るし、15にすれば
AAAA
と、出る。
sedのバージョンと実データがどんなのか知りたい所。
196:login:Penguin
07/09/18 18:48:06 mMDRvNP8
>>195
スマソが懽の隣の文字のフォントが無いのだが
E3
5E
って表示になってる
197:login:Penguin
07/09/18 19:09:24 AGCqK3mV
半角カナで書いたら化けた模様w
198:login:Penguin
07/09/18 21:50:07 En+WDn3C
bashでスクリプトと組んでいる途中でつまづいてしまいました
~/tmp/ 以下にあるファイルすべてに対してファイル変換したいのです(例 aaaaa ⇒ aaaaa.txt)
~/tmp/aaaaa
~/tmp/bbbbb
:
~/tmp/nnnnn
=============
cd ~/tmp/
ls_result1=`ls`
for list1 in $ls_result1
do
#便宜上 (変換コマンド) (変換前) (変換後) とします
(変換コマンド) ~/tmp/$(list1) ~/tmp/tmp/$(list1).txt ←listの使い方が間違っているのだと思います
done
=============
list1 not found というエラーがたくさん出てきてしまい困っております。
~/tmp/ 以下にあるファイル名をそのまま使いたいので、どなたかご教授ください。
199:login:Penguin
07/09/18 22:05:47 9R+Y1frn
>>198
×(変換コマンド) ~/tmp/$(list1) ~/tmp/tmp/$(list1).txt
○(変換コマンド) ~/tmp/${list1} ~/tmp/tmp/${list1}.txt
200:198
07/09/18 22:15:47 En+WDn3C
>>199
できました♪ ありがとうございました m(_ _)m
201:login:Penguin
07/09/19 06:55:54 OLZv4Z+v
sed で/、\を多用できるようになりますたww
\tとか技も覚えますたww
みなさんdd!
202:198
07/09/19 12:51:22 OlaeIc6l
~/tmp/ 以下にある txtファイル だけファイルの中で置換したいのですが、
またつまづいてしまいました
# その前の処理で year month day hour という変数が与えられています
txtファイルの1行目 2007090100AB ⇒ year month day hour AB(変数の間のスペースなし、ABは固定文字列)
txtファイルの2行目 2007/09/01 ⇒ year/month/day
そこで以下のように作ったのですが、~/tmp/ に bakファイルが作られておらず、
echo $ls_result を見ると /home/myname/tmp/*.txt となっていました
想定では *.txt だったのですが・・・
=================
ls_result=`ls ~/tmp/*.txt`
for list in $ls_result
do
cp -p $list ${list}.bak
sed -e '1 s/2007090100AB/${year}${month}${day}${hour}AB/' ${list}.bak
sed -e '2 s/2007\/09\/01/${year}\/${month}\/${day}/' ${list}.bak
mv &{list}.bak $list
#rm -f ${list}.bak
=================
どなたか教えてください。よろしくお願いします。
203:login:Penguin
07/09/19 15:41:53 Ii4uF/l/
これではまともに動いてもbakファイルはないだろ
204:login:Penguin
07/09/19 18:36:32 42fTFu0H
>>202
これだと置換後のファイルを.bakに作って、そのあと出来た.bakをオリジナルに
重ね書き(しかもムーヴ)してるように見えるけど。
.bakとオリジナルの2個とも残したいなら、mvじゃなくてcpだろうね。
それ以前に、こういう処理だと普通は.bakに変換前のオリジナルを残すと思うが。
最初にオリジナルを.bakにcpしてあるんだから、.bakは触らずに、元のファイルに
sedかけて、最後のmvは不要では
205:198
07/09/19 20:34:50 OlaeIc6l
>>203-204
コメントありがとうございます
いただいたアドバイスどおり、bakにはさわらずにオリジナルでsedかけてみました
ところが、シェルを動かした後のファイルを見ると動かす前とまったく同じ状態でした。
タイムスタンプも動かす前と同じでした。
sedの使い方が間違っているのでしょうか。今一度教えてください。
=================
ls_result=`ls ~/tmp/*.txt`
for list in $ls_result
do
cp -p $list ${list}.bak
sed -e '1 s/2007090100AB/${year}${month}${day}${hour}AB/' ${list}
sed -e '2 s/2007\/09\/01/${year}\/${month}\/${day}/' ${list}
#rm -f ${list}.bak
=================
206:login:Penguin
07/09/19 20:37:21 NIZBsTRK
>205
sedは-iオプションを指定しないと結果を標準出力に書き出すだけだよ。
207:login:Penguin
07/09/19 21:25:46 gh8Zvftq
sed -i.bak -s \
-e "1s/2007090100AB/${year}${month}${day}${hour}AB/" \
-e "2s,2007/09/01,${year}/${month}/${day}," \
~/tmp/*.txt
で、よくね?
208:198
07/09/19 21:44:56 OlaeIc6l
>>203-204,206-207
207さんのとおりにしたら、想定どおりに動きました!
みなさんありがとうございました。m(_ _)m
ずっと調べてたらこんな時間に…
今からごはん作ります (^o^)/
209:login:Penguin
07/09/21 15:18:02 5N/Tidqv
ディレクトリーA(ファイルが入ってます)を
10/1〜10/31の日付名でコピーしたいのですが
なんかいい方法無いでしょうか?
Zshだと cp -R A 10[1-31]なんてできるのでしょうか?
210:login:Penguin
07/09/21 15:27:31 KLJI/R6G
>>209
for i in {01..31}; do cp -pR A A10$i; done
zsh と bash で挙動違うな。
211:login:Penguin
07/09/21 15:37:28 KLJI/R6G
>>209
< - > のことなら、ちょっと用途が違うよ。
こんなんやってみ。
% touch B2
% ls B{1..3}
% ls B<1-3>
212:login:Penguin
07/09/21 15:46:39 5N/Tidqv
>>210 ハヤッ! ありがとうございます!
ディレクトリーAにhoge01〜100ってファイルを作ったときは
Zshでさらさら〜って逝けたのですが
現在bash環境なのでそれなりに書かないといかんなと思いつつ
3行になってしまう、漏れの脳みそでした il||li○| ̄|_
1行でやりたかったww さすがです>>210様 1行でばっちりコピーできますた
213:login:Penguin
07/09/21 15:49:11 5N/Tidqv
>>211 すみません −じゃなくて..でした
なかなか参考になるスッドレですね
正規表現もきっちり覚えないといけませんねorz
214:login:Penguin
07/09/22 04:00:27 DSw3XQMb
for d in {01..31} ; do printf "%02d " $d; done
215:73ですが
07/09/22 22:02:55 TBL9KN2J
>>94
おくればせながらスクリプトが動くようになりました。
御指摘のとおりスペースの数などがあっていませんでした。
ありがとうございました。
216:login:Penguin
07/09/26 09:48:46 kfTmpMA+
時間の逆算っていい技ないですか?
やぱ現在時刻から60進法で計算したほうが早い?
現在時刻 21:24 残り時間 36分で22時 って感じ
で、やてみたい
217:login:Penguin
07/09/26 09:54:08 lgPbyfYB
>>216
coreutilsのdateを使う。
218:login:Penguin
07/09/26 13:11:02 kfTmpMA+
date --date xxmin とかできるのですね!!
しらなんだポカーン
>>217 ありがdクス
219:login:Penguin
07/09/26 14:13:45 kfTmpMA+
echo $((59 -` date '+%M' | awk '{print $1}'` )) $((59 -` date '+%S' | awk '{print $1}'` ))
これでもでけた!
220:login:Penguin
07/09/27 18:47:27 Qh1DP+hx
date,sleep, atは使い込めばラーメンタイマーも・・・・・・・いやなんでもない
221:login:Penguin
07/10/02 23:24:08 57QYWA2W
ほしゅ
222:login:Penguin
07/10/09 18:07:07 lJCQFIXV
モデムをオンフックにするのに
今のところcuを使って対話的にATH0を
送っているのですが、これを
シェルスクリプト内で実行して
自動化する方法はありますか?
223:login:Penguin
07/10/09 23:58:35 rK7+VmTA
対話的といえば expect ぐらいしか思いつかないな
224:222
07/10/10 19:31:25 TchaYqjx
>>223
manを眺めましたが奥が深そうですね。じっくりと勉強してみます。
ありがとうございました。
225:login:Penguin
07/10/11 00:25:04 0rD2It5e
>>222
草の根BBSでもやるんかい?
226:login:Penguin
07/10/11 02:33:49 8ZTBNRII
モデムで思い出したが、ミャンマーで対外ネット回線が一時遮断されたって
報じてたじゃん。
こんなときにもなんとかなるよう在外公館にアナログモデムを常備してたりは
しないだろうか。
227:222
07/10/11 06:32:06 o32fDZEh
>>225
これまでCCT-98IIIのマクロで自動巡回してたんですが
Linuxにしたら使えなくなるそうなので・・・・。
って、いやそうじゃなくて、vgettyで留守電のテストを
やってたら回線をつかんだまま切れないことがあって
それを切断させたいわけです。
>>226
自分はいざというときのためにジャストシステム製の
音響カプラ持ってます。(処分してないだけかも)
228:login:Penguin
07/10/11 08:26:20 A6nFaf5V
kermitをperlで操作するnifty4uというパッケージが、前世紀にあった。
NIFTY フォーラム自動巡回スクリプトなので、CCT-98な人には改造が容易かも。
ダイアルアップpppスクリプトを書けば済むんじゃないかと思うけど、やったことないから分かりません。。。
229:login:Penguin
07/10/11 13:36:28 wykYuUw8
#!/bin/bash
cd /home/hogehoge
というシェルスクリプトを作成し、実行してみても、移動でき
ません。
ディレクトリを移動するにはどのようなスクリプトを書けばい
いでしょうか?
230:login:Penguin
07/10/11 13:41:47 wNnhF+3E
>>229
シェルスクリプトとバッチファイルは違う。
シェルスクリプトはシェル内で動作する子プロセスだ。
231:login:Penguin
07/10/11 13:44:37 wNnhF+3E
>>229>>230
一部訂正。
s/シェルスクリプトは/単純に実行したシェルスクリプトは/
解決方法は "source" 。
232:229
07/10/11 14:10:15 wykYuUw8
>>230>>231
ありがとう。今手元に環境がないので明日試してみます。
233:login:Penguin
07/10/11 18:43:47 KODaF1AT
>>232
shell.sh がシェルスクリプトのファイル名だとして
chmod a+x shell.sh で実行権限与えて
shell.shがあるディレクトリで
./shell.sh
したら移動するよ。
234:229
07/10/12 09:38:40 EbLcx1Gh
>>231
sourceやってみたら無事cd出来ました。
>>233
やってみたけど、上手くいきませんでした。
お二方ともありがとうございました。
235:login:Penguin
07/10/12 10:44:01 7zE2B01m
シェルプロンプトにコマンド名を叩き込んで実行すると、
子シェル(sh,cshなど)が新たに作られて、その子シェルがスクリプトを実行する。
で、スクリプトが終わるとその子シェルもろとも消えて親シェルに戻ってくる。
だから、シェルスクリプト内でcdしたり、環境変数をセットしても、その影響は
子シェルの中にとどまって、スクリプト終了と共に消えてなくなる。
cshのsourceやshの.(ドット)は、子シェルを作らないで自分の中でスクリプトを実行する。
だからcdやsetenv、exportの結果が、起動した親シェルに反映される
236:login:Penguin
07/10/12 11:22:55 5+kNLqtp
. の他に alias とか関数使う手もあるよ。
237:233
07/10/12 17:40:09 sUVuIX9s
>>234
ごめん!間違った。
./shell.sh じゃなくて
. ./shell.sh でした。
. を打って1個スペース空けて シェルスクリプトファイル指定。
238:login:Penguin
07/10/12 17:46:35 5+kNLqtp
>>237
なんで ./ を付けるの?
239:login:Penguin
07/10/12 17:59:22 +Kk0eMQd
Yeah!めっちゃホリデイ
240:login:Penguin
07/10/15 14:50:05 NjtHefoB
特定のURLを一定時間に読み込むシェルスクリプトをつくりたいのです。
今のところwgetを使ってwget URLリンク(hogehoge) をクーロンで動かす予定ですが
もっとスマートなやりかたはありますか?
241:login:Penguin
07/10/15 22:15:04 yaqxWPIK
>>240
それでいいんじゃね?
242:login:Penguin
07/10/15 23:35:58 6xnjJ9Cn
>>241
じゃあ1分に1回よりも高頻度(30秒に1回とか、15秒に1回とか) やりたい場合はどうすれば?
243:login:Penguin
07/10/16 00:24:31 7lwU6GvW
アタックしたいのか?
244:login:Penguin
07/10/16 01:36:38 IhGBMLbJ
>>242
wget URLリンク(...;)<)
するスクリプトを毎分実行するとか。
245:login:Penguin
07/10/16 08:18:30 a72PxkLH
>>243
アタックしたいわけじゃないですよ。
ただcronって最高でも1分に1回しか実行できないはずなので、それよりももっと短い間隔で
処理をさせたい場合とかどうするのかなぁとふと疑問に思ったもので。
>>244
なるほど・・。 しかし wget URLリンク(...)<) がくるから、タイミングと言うか場合によっては
30分に1回キッチリ実行されるとは限りませんね。31分かかって、その後実行されて
今度は29分後に実行されるみたいなズレ方はしますよね。
246:login:Penguin
07/10/16 08:26:34 IhGBMLbJ
>>245
バックグラウンドで実行するとか。
つーか、何分もかかる処理を30秒ごとに実行していいのか?
247:login:Penguin
07/10/16 11:46:31 wfMufGFC
cronはプロセスが無限増殖するのを抑えるために、同時実行数に制限があるので注意
Solarisだと、確か同時実行数が100個を超えるとそれ以降は時刻が来ても起動しなくなる
LinuxだとOOMキラーが動いて刈り取られるかもしれん
cronの起動間隔 ≒ プロセスの実行時間
となるような長めのプロセス、特に通信関係とかで長めのタイムアウトが発生しそうな
プロセスをcronに仕込むときは、注意したほうがいい
248:229
07/10/16 13:58:23 EtpWijek
環境が手元にないもので、遅レスになってしまいすみません。
>>235
なるほどです。ありがとうございました。
>>236
ありがとう。aliasでも出来そうでした。
>>237
.の後に続けて入力したところ、うまくcdできました。
>>238
素人なのでよく分かりませんが、実行ファイルを実行するときに付けるんでは?
それでは、みなさんありがとうございました。
249:login:Penguin
07/10/16 14:09:44 IhGBMLbJ
>>248
. shell.sh
でもいっしょだよ。
やってみ。
250:login:Penguin
07/10/16 17:45:32 a72PxkLH
./ を つけるのは カレントディレクトリのファイルを指定する為。
つけないと 環境変数 $PATH の中から該当する物が無いかを探してなかったら
エラー返すので。 カレントディレクトリのファイルを指定する時にいちいち
./ をつけるのが面倒だからって $PATH に ./ も含めてしまうとセキュリティホールになるので
やらないでね。
251:login:Penguin
07/10/16 17:50:59 IhGBMLbJ
>>250
>>249
252:login:Penguin
07/10/16 18:39:11 tU6zGUOB
シェルスクリプトで端末の現在の行数を得るにはどうしたらいいですか
253:login:Penguin
07/10/16 19:18:04 iHfKM46h
stty -a とかかな。
254:login:Penguin
07/10/16 19:45:06 tU6zGUOB
>>253
情報ありがとうございます。
行数を表示するだけでなくて、
シェルスクリプトの中で行数を変数に格納して、
なんらかの処理を行いたいと思っているのですが
何かうまい方法はありますでしょうか
255:login:Penguin
07/10/16 21:12:10 pdm4T3SF
>>254
ROWS=`stty -a | tr ";" "\n" | grep rows | sed "s/.*rows //"`
256:login:Penguin
07/10/16 21:36:05 tU6zGUOB
>>255
できましたありがとうございました。
257:login:Penguin
07/10/16 23:32:43 sWAUZpv3
$LINES じゃだめなの?
258:login:Penguin
07/10/17 04:58:42 d5Vjha9K
シェルスクリプトの中で$LINESがとれるとでも?
259:login:Penguin
07/10/17 10:00:57 9KXOUzKW
ROWS=`tput lines`
COLS=`tput cols`
260:login:Penguin
07/10/17 22:15:42 VuOM9tU/
eval `resize`
echo $LINES $COLUMNS
261:login:Penguin
07/10/18 12:39:19 fyMSNeWa
>>260
resize は X がインストールされていない環境では使えない。
xterm の付属物なので。
262:login:Penguin
07/10/23 17:14:39 OMh5qn/O
ちょっと相談に乗ってください。
日付.pc名.サイト名_access_log
ex)
20071023.pc-local01.hoge_access_log
20071023.pc-local02.hoge_access_log
20071023.pc-local01.hagehoge_access_log
20071023.pc-local02.testhoge_access_log
と言うログファイルをサイト名別のフォルダに移動した後
1つのログファイルにマージさせるスクリプトを書きたいのですが。
とりあえず、スクリプト書いてみたのですが正直何がなんだか
分かりません。アドバイスを下さい。
#!/bin/sh
timestamp=`date +%Y%m%d`
log=`find /home/hoge/log -name $timestamp.*`
list=`echo "$log" | sed -e 's/_access_log//g' | cut -c57-`
スクリプトでは、今日のタイムスタンプを取ってlogファイルを検索し
その結果のサイト名以降の”_access_log”を消して、サイト名より前
も入らないので、表示させないようにする。これから、サイト別にフォルダを
作ってそこに移動させるのですが、mkdir "$list"では上手く行きません。
何かいいアドバイスを教えてください。よろしく御願いします。
263:login:Penguin
07/10/23 17:19:48 4jX2ZQqu
>>262
cut -c57- ってのは何?
264:login:Penguin
07/10/23 17:20:31 XqFIvlF4
>>262
シェルスクリプト以前の話だな。
まずは最終的に何をやりたいのかをはっきりしろ。
265:login:Penguin
07/10/23 17:26:06 4jX2ZQqu
>>262
$log にたくさんファイル名が入ってるのに
echo $log をいじろうとするのがよくわからんな。
>>264
まずは日本語の勉強からだな。
266:login:Penguin
07/10/23 17:50:56 OMh5qn/O
>>263
サイト名だけの文字を取りたかったので、cut -c57- としました。
>>264
申し訳御座いません。
ログファイル名からサイト名だけを文字を取り出して、取り出した文字
(サイト名)のフォルダを作って、作ったフォルダにそれぞれログを
振り分けてログファイルをマージさせたいです。
これで、少しは伝わりますでしょうか?
>>265
$logの結果からサイト名の文字だけ取りたかったので、echo $logを
いじっています。
267:login:Penguin
07/10/23 18:08:13 XqFIvlF4
>>266
プログラミングの論理部分を勉強したほうがいい。
「やりたいこと」と「実際のスクリプト」の間には
「ロジックを組み上げる」作業が必要になるが、
君はこの部分について全く理解できていないようだ。
まずは
「findで検索したファイルの一覧はどういう形で変数logに入っているのか」
「その変数logに対して繰り返し処理を行なうにはどうしたらよいか」
を調べてくるべし。
268:login:Penguin
07/10/23 18:09:14 4jX2ZQqu
そもそも find でうまくいかんな。
269:login:Penguin
07/10/23 18:17:19 OI+rqPpl
>>262
find . -type f -printf %f\\n|awk -F. '{gsub(/_access_log/,"",$3);print $2 "." $3}'|uniq >hostlist
for i in $(cat hostlist);do mkdir $i;done
あとawkで同じように
cp 20071023.pc-local02.testhoge_access_log pc-local02.testhoge
のようなlist作って実行
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5366日前に更新/275 KB
担当:undef