トップページunix
988コメント297KB

シェルスクリプト総合 その24©5ch.net

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。 転載ダメ©2ch.net2014/11/11(火) 00:54:03.43
シェルスクリプトの総合スレです。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。
 FreeBSDユーザは/bin/shの正体がashなので注意。
 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
  http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
  http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
 (理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)
・シェルスクリプトのことをシェルってゆーな
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 awkまたはperlの方が適した処理にはそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
□回答者への注意事項:
・シェルスクリプトでの処理方法を質問しているのに、よくわからずに
 「そういうのはperl使いましょう」と回答するのはやめましょう。
 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その23
http://peace.2ch.net/test/read.cgi/unix/1404204950/
0363名無しさん@お腹いっぱい。2015/02/24(火) 22:43:45.95
文字ではなく単語単位だと
マッチ部分が重複するケースもあると思うけど
そういう時はどう書けばいいんだろ

$ echo ABC | grep -Po '..'
AB
$ echo ABC | grep -Po '.(?=.)'
A
B

$ echo ABC | ?
AB
BC
が欲しい
0364名無しさん@お腹いっぱい。2015/02/24(火) 22:45:35.14
真髄ねー
0365名無しさん@お腹いっぱい。2015/02/24(火) 23:11:13.94
>>362
>>348とかどうよ?
0366名無しさん@お腹いっぱい。2015/02/25(水) 10:15:56.15
>>355
お前は4時間以上かけてそんな回答しかできないのか
0367名無しさん@お腹いっぱい。2015/02/25(水) 10:36:23.41
20時間以上かけた回答に期待
0368名無しさん@お腹いっぱい。2015/02/25(水) 21:30:04.01
str='>>350 ネタ2です。
ところで、あるテキストや特定のキャラクタは utf-8 であると考える必要性は有りや無しや。
神に問う。信頼は罪なりや。 果たして、無垢の信頼心は、罪の源泉なりや。'

echo "$str" | grep -o . | LC_COLLATE=C sort | uniq -c
echo "$str" | perl -0777 -ne 'print s/。//g,"\n"'
0369名無しさん@お腹いっぱい。2015/02/25(水) 22:36:30.27
>>365
楽しそうだね。でも、GUIの操作をすべてコマンドからやりたいよ。
オブジェクトでも作る?
0370名無しさん@お腹いっぱい。2015/02/25(水) 22:47:56.06
xteじゃダメ? ドラッグの仕方はよくわからんが。
0371名無しさん@お腹いっぱい。2015/03/02(月) 23:05:19.70
明日以降は、ここを見る回数も減るかもしれない。みなさん一応さようなら
ネタは不評だったけど、最後かもしれないし >>363 にも答えておこう。
perl と ruby で

#!/bin/sh
echo '商工会議所長' |
 perl -ne 'while( /(?=(会議所|所長))/g ){ print $1, "\n"; }'

echo '商工会議所長' |
 ruby -Ku -ne 'puts $_.scan( /(?=(会議所|所長))/ ).join( "\n" )'
0372名無しさん@お腹いっぱい。2015/03/02(月) 23:11:47.85
>>348で落としてdat変換位、スクリプトで出来ないかな?
0373名無しさん@お腹いっぱい。2015/03/03(火) 03:08:17.32
>>371
何がなんだか…w
0374名無しさん@お腹いっぱい。2015/03/03(火) 08:07:50.39
>>371って問題がわかってないよな
「aaaaaaaaaa」に対して「aa」が
どうマッチするかってことなんだけど
なんで会議所と所長になっちゃうんだろうかw
脳味噌足りてなさそう
0375名無しさん@お腹いっぱい。2015/03/03(火) 17:30:06.70
$ echo 'ABC' | perl -ne 'while( /(?=(AB|BC))/g ){ print $1, "\n"; }'
AB
BC

じゃまずいのかな。
03763712015/03/04(水) 06:55:50.72
>>375
>>374 に対しての発言の様にも取れるけど、>>371 に対しての発言ならば...
それも試した上で、書いてる

無反応だったけど >>368 で utf-8 である事を考えていないものが有る事を指摘したので
引き続き、>>363 のお題
> 単語単位だとマッチ部分が重複するケース
に沿って、日本語に入れ替えただけ
0377名無しさん@お腹いっぱい。2015/03/04(水) 13:23:38.19
>>363は任意のテキストに使える記述を期待してるんじゃないだろうか
所長と会議所限定じゃなく
03783632015/03/04(水) 22:12:28.21
>>377
いや…
スレタイ的にLL言語に頼らないやり方を期待してた
0379名無しさん@お腹いっぱい。2015/03/04(水) 22:57:35.29
スレとあんま関係ないんだけど、
みんなどんな時も/bin/sh縛りなの(´・ω・`)?

それとも割と躊躇なく、bashとかzsh使うの(´・ω・`)?

使う人はどういう線引きで/bin/shと高機能シェルを使い分けてるの(´・ω・`)?
0380名無しさん@お腹いっぱい。2015/03/04(水) 23:04:13.67
スレと関係ないからよそでやってくれる?
03813712015/03/06(金) 06:31:41.84
>>353 でも perl は使われているのだが、ワンライナーも許されませんか

wikipedia で LL言語を見ると、awk も AUTO だけど、sed は入っていなかったので
sed を使って無理やり書いてみよう
.*? が使えないので .. みたいな正規表現への対応は思いつけなかったけど、単語を抜き出すだけならこれで

#!/bin/sh
re1=${1:-会議所\|所長}
str=$re1
while
 re2=$re2$( echo "$str" | sed -e 's/^\(.\).*/\1/' )
 length=${#str}
 str=${str#*|}
 [ "${#str}" -ne "$length" ]
do
 :
done

# ここから
sed -ne '
 : loop
 /'"$re1"'/ {
  s/^[^'"$re2"']*\('"$re1"'\)/\1\n/
  P
  s/^.\(.*\)\n/\1/
  b loop
 }
'
0382名無しさん@お腹いっぱい。2015/03/06(金) 06:33:59.92
bash でも

#!/bin/bash
re1=${1:-会議所\|所長}
str=$re1
while
 re2=$re2${str:0:1}
 length=${#str}
 str=${str#*|}
 [ "${#str}" -ne "$length" ]
do
 :
done

while
 IFS= read -r line
do
 while
  [[ "$line" =~ ^[^${re2}]*((${re1}).*) ]]
 do
  echo "${BASH_REMATCH[2]}"
  line=${BASH_REMATCH[1]}
  line=${line#?}
 done
done
0383名無しさん@お腹いっぱい。2015/03/06(金) 06:36:18.16
使用例

$ echo 'abc' | ./testsed 'ab\|bc'
ab
bc

$ echo 'abc' | ./testbash 'a.|b.'
ab
bc
03843712015/03/06(金) 07:34:31.86
訂正
全般的に変数代入の箇所のクォート
var="var"


#!/bin/bash
re1="${1:-会議所|所長} "
0385名無しさん@お腹いっぱい。2015/03/06(金) 08:05:27.13
読む気もおきないです本当にありがとうございました
0386名無しさん@お腹いっぱい。2015/03/06(金) 09:15:28.00
371って問題が理解できてない残念な子だな
0387名無しさん@お腹いっぱい。2015/03/08(日) 00:18:10.47
>>379
個人用とか、そのマシンに特化したスクリプトならbashだろうがzshだろうが何でもアリだけど
普段から/bin/sh縛りにしておくと、違うマシンでもスクリプトが書けるようになるぞ
0388名無しさん@お腹いっぱい。2015/03/08(日) 03:45:15.37
と思うだろ。
でも実際は変な癖がそれぞれついてるんで、あまり役に立たない。
0389名無しさん@お腹いっぱい。2015/03/08(日) 05:35:53.00
bash拡張を使うなら#!/bin/bash
0390名無しさん@お腹いっぱい。2015/03/08(日) 05:57:27.23
>>389
bashが/bin/にない環境もあるで
0391名無しさん@お腹いっぱい。2015/03/08(日) 07:00:32.87
/bin/tcsh縛りで書いてるw
0392名無しさん@お腹いっぱい。2015/03/08(日) 08:29:58.08
busyboxのsh縛りが実用的。

#!/sbin/busybox sh

と書くこと。
0393名無しさん@お腹いっぱい。2015/03/09(月) 01:03:57.32
>>391
害悪。
君個人しか絶対使わないマシン以外は触らないで。
0394前スレ1192015/03/11(水) 18:57:08.87
前スレ119です。その節はお世話になりました。
さて、プレーンテキスト中の

hoge_01_bar.pdf
hoge_01_foo.pdf
hoge_02_bar.pdf
hoge_02_foo.pdf
。。。
hoge_58_foo.pdf
hoge_59_bar.pdf
hoge_59_foo.pdf
hoge_60_bar.pdf
hoge_60_foo.pdf



hoge_{01..60}_bar.pdf
hoge_{01..60}_foo.pdf

に置換したいのですがどうすればできますか?
よろしくお願いします。
0395前スレ1192015/03/11(水) 19:13:00.82
追加で申し訳ないです。hoge部はhoge1、hoge2、piyo00_piyo01など入り乱れてるのが
同じtree.txt中に混在している状況です。
数字の部分も

01_{01..07} #(実際は7行ある)、
...
04_{01..04} #(これも4行ある)

になっているブロックもあったりしてかなりヤヤコシイのですが、
[(連番になっている数字)以外のところが同じ行]を検出して数字を{}でまとめたい感じです。
3000行あって手作業は泣きそうなので、エレガントな方法をご教授いただければ幸いです。
{01..04}_{01..07}とする必要は無いです。
よろしくお願いします。
0396名無しさん@お腹いっぱい。2015/03/11(水) 19:16:18.16
そういうのはシェルで書きたくないな
0397名無しさん@お腹いっぱい。2015/03/11(水) 19:54:30.56
とりあえずソートしようぜ
0398名無しさん@お腹いっぱい。2015/03/11(水) 20:19:19.48
>>396
何で書くの(´・ω・`)?
0399名無しさん@お腹いっぱい。2015/03/11(水) 20:27:02.77
perlでもrubyでもpythonでも好きなのでいいよ
0400名無しさん@お腹いっぱい。2015/03/11(水) 20:48:55.55
>>394,395
ご自分が言っているように、まず
>[(連番になっている数字)以外のところが同じ行]を検出して
これをする。たとえば次のように
sed -e 's/_[0-9][0-9]_/_%%_/' tree.txt | sort | uniq
これで「連番になっている数字以外のところが同じ行」をパターン化できる
そしたら、そのそれぞれのパターンで grep tree.txt して、sort -n し、
head -n 1 と tail -n 1 で連番の最初と最後の値を切り出す

こんな感じで行けないかな
0401名無しさん@お腹いっぱい。2015/03/11(水) 20:58:26.70
なんのアイデアもなくすまんが、連番かどうか見るのがめんどくさそうですね
0402名無しさん@お腹いっぱい。2015/03/11(水) 23:14:35.24
すまん
問題が全然理解出来ない
誰か問題を解説してくれ
0403名無しさん@お腹いっぱい。2015/03/11(水) 23:20:28.51
もともとは韓国領だったが、
日本の植民地支配から、
日本が勝手に領有権を主張しだした。
現在は国際的にも韓国領と認識されている。
0404名無しさん@お腹いっぱい。2015/03/11(水) 23:54:15.14
北朝鮮のことか。
0405名無しさん@お腹いっぱい。2015/03/12(木) 00:03:26.06
理解できないなら無理に答えようとしなくていい
0406名無しさん@お腹いっぱい。2015/03/12(木) 01:56:20.20
独島は韓国領だよ。
やつらの主張の誤りは、独島=竹島だと言張ってるところ。
独島は竹島だとは別の島だよ。
0407名無しさん@お腹いっぱい。2015/03/12(木) 02:02:58.54
石島とか言ってたソビエトみたいな島の事?
0408名無しさん@お腹いっぱい。2015/03/12(木) 02:46:00.10
>>402
Bashのブレース展開の逆がやりたいってことかと
0409名無しさん@お腹いっぱい。2015/03/12(木) 03:03:37.86
perlのモジュールで
http://search.cpan.org/~vvu/Compress-BraceExpansion-0.1.7/lib/Compress/BraceExpansion.pm
てのがあった
このままじゃ使いものにならんけどね
0410名無しさん@お腹いっぱい。2015/03/12(木) 16:01:30.66
ちょっとお知恵を拝借したい
テキストファイルを検索して見つけた行数を取得したいときって
grep -nで行数出力させて取得するのが一番シンプルかな?
マッチする最終行にしたい場合はtailと組み合わせてさ

ちなみにシェル知らなかったころってreadで1行ずつ読み込んで判断してたw
0411名無しさん@お腹いっぱい。2015/03/12(木) 16:32:34.70
「一番」って難しいこと聞くね
0412名無しさん@お腹いっぱい。2015/03/12(木) 18:00:51.55
>>410
grep -c
0413名無しさん@お腹いっぱい。2015/03/12(木) 18:40:40.82
>>412
オマエいつも問題の意味取り違えて回答して点数もらえないタイプだろw
0414名無しさん@お腹いっぱい。2015/03/12(木) 20:35:27.12
>>413
ん?
質問:検索して見つけた行数を取得したい
cオプション: 検索条件にマッチした行数を表示する
0415名無しさん@お腹いっぱい。2015/03/12(木) 20:36:26.22
>>413
あ、わかった
質問は行番号のことを行数といっているのね
0416名無しさん@お腹いっぱい。2015/03/12(木) 20:36:37.62
>>414
まだわかってないのか…重症?
0417名無しさん@お腹いっぱい。2015/03/12(木) 21:26:36.04
ちょっとwc
0418名無しさん@お腹いっぱい。2015/03/12(木) 22:07:04.23
>>417
オプションなしだと複数返すコマンドだよね
0419名無しさん@お腹いっぱい。2015/03/13(金) 00:23:15.74
行数と行番号じゃ、意味が違うな。
日本語に不自由してるのぅ
0420名無しさん@お腹いっぱい。2015/03/13(金) 01:03:30.38
grep -nで出力されるのは行数ではないね
0421名無しさん@お腹いっぱい。2015/03/13(金) 01:16:54.86
なんかgrep -c言ってる人がバカにされてるけど
>grep -nで行数出力させて取得するのが一番シンプルかな?
>マッチする最終行にしたい場合はtailと組み合わせてさ
これから察するに、行数と書いてはいるが、実際は行数じゃなくて行番号のこと言ってるんじゃないの?
マッチした行数が知りたいなら最終行の話なんて出てこないだろ

つまり本当にバカなのは>>416と推測
まぁ質問主から続きがなければ有耶無耶だが
04224212015/03/13(金) 01:17:57.58
俺何言ってんだ?
すまん眠かったってことで何も見なかったことにしてくれ……死ぬ……
0423名無しさん@お腹いっぱい。2015/03/13(金) 04:43:04.00
行数、直訳すると line number
0424名無しさん@お腹いっぱい。2015/03/13(金) 07:28:39.51
line countじゃないの?
0425名無しさん@お腹いっぱい。2015/03/13(金) 07:40:15.74
直訳、と言ってるだろ。

natural number = 自然数
complex number = 複素数
number = 数
0426名無しさん@お腹いっぱい。2015/03/13(金) 08:04:07.16
>number = 数

ちがう。
0427名無しさん@お腹いっぱい。2015/03/13(金) 08:20:54.53
違うの知ってて言ってんでしょ
0428名無しさん@お腹いっぱい。2015/03/13(金) 11:04:35.04
順序数?
0429名無しさん@お腹いっぱい。2015/03/13(金) 13:12:27.06
行番号を行数と呼ぶ人がいるとして、その人は行数を何と呼ぶのでしょうかね。行の数?
0430名無しさん@お腹いっぱい。2015/03/13(金) 17:11:36.57
行回数
0431名無しさん@お腹いっぱい。2015/03/14(土) 01:06:12.05
行数はnumber of linesだろ
Fランもたいがいにせいよ
0432名無しさん@お腹いっぱい。2015/03/14(土) 02:26:16.92
>>410
まあgrepでいいと思う

grep -n regexp FILE | tail -n1 | cut -d: -f1
awk /regexp/'{print NR}' FILE | tail -n1
sed -n /regexp/= FILE | tail -n1
0433名無しさん@お腹いっぱい。2015/03/14(土) 04:57:44.74
>>431
行数は line count (だからこそ grep -c )
0434名無しさん@お腹いっぱい。2015/03/14(土) 05:17:25.87
count number of lines じゃね
てかどーでもいいよ
行数にしろ行番号にしろ質問者が具体例を明示してる時点で誤解しようがないだろ
早がってんしたエスパースキルゼロのうっかりさんが
早漏の言い訳をぐだぐだぐだぐだぐだぐだぐだぐだぐだぐだ
くだらねー
0435名無しさん@お腹いっぱい。2015/03/14(土) 05:44:10.73
それは「行数を数えろ」だろ
中卒もたいがいにしとけ
0436名無しさん@お腹いっぱい。2015/03/14(土) 07:03:54.77
>>435
countは動詞だけじゃなく名詞にもなるんだよ、知らなかった?
0437名無しさん@お腹いっぱい。2015/03/14(土) 08:50:28.21
へー
0438名無しさん@お腹いっぱい。2015/03/14(土) 18:41:01.09
>>436
名詞が連続してるが、それはどう言い訳するんだ?
0439名無しさん@お腹いっぱい。2015/03/14(土) 21:16:03.47
http://www.gnu.org/software/grep/manual/grep.html#General-Output-Control
-c
--count
Suppress normal output; instead print a count of matching lines for each input file. With the -v (--invert-match) option, count non-matching lines. (-c is specified by POSIX.)
0440名無しさん@お腹いっぱい。2015/03/15(日) 00:27:31.56
一行の中に、
bbbbaaa124iiiiiccccaaaa456lllllddddaaa789と書いてあった場合に、
特定の文字列の後に続いている数字を、スペース空けて抜き出す書き方はないでしょうか
うえの場合だとaaaの後にあるものを抜き出すように、124 456 789のような・・
素人質問ですいませんがよろしくお願いします
0441名無しさん@お腹いっぱい。2015/03/15(日) 01:12:54.15
GNU grep が使えるなら

$ echo "bbbbaaa124iiiiiccccaaaa456lllllddddaaa789" | grep -Po '(?!aaa)[[:digit:]]+' | tr '\n' ' '
0442名無しさん@お腹いっぱい。2015/03/15(日) 02:09:05.45
>>441
できました!
使わせていただきます。ご親切にありがとうございました。
0443名無しさん@お腹いっぱい。2015/03/15(日) 03:20:18.84
追加で質問したいのですが、
上の例でbbbbaaa124iiiiicccc222aaaa456lllllddddaaa789とあった場合に、
aaaの直後でない222は省いて124 456 789だけ方法はないでしょうか
何度もすいません
0444名無しさん@お腹いっぱい。2015/03/15(日) 03:27:09.47
grep -Po '(?<=aaa)\d+'
0445名無しさん@お腹いっぱい。2015/03/15(日) 03:50:51.90
>>444
完璧にできました!
この時間に回答いただけるとは思いませんでした。
大変助かりました。ありがとうございました。
0446名無しさん@お腹いっぱい。2015/03/15(日) 13:29:40.91
何度もすいません
上の例で、bbbbaaa0.24iiiiicccc2.22aaaa456lllllddddaaa7.89 など
小数点も含む数字が混じっている場合に、同様の条件で0.24 456 7.9を抜き出す方法はないでしょうか
あまりにも聞きすぎなので最後にしようと思います。
0447名無しさん@お腹いっぱい。2015/03/15(日) 14:11:57.45
こうかなぁ…

grep -Po '(?<=aaa)\d+(\.\d+)?

でもこれだと、".01" とかにはマッチしないけどね。
それと、"1.2.3" なんて文字列があると、"1.2" にマッチしちゃう。
0448名無しさん@お腹いっぱい。2015/03/15(日) 14:12:54.78
ちったぁ自分で考えな
過去2回の答えがなぜそうなるのかを考えれば応用でいけるはずだ
0449名無しさん@お腹いっぱい。2015/03/15(日) 14:15:07.46
grep -o 'aaa[0-9\.][0-9\.]' | tr '\n' ' '
0450名無しさん@お腹いっぱい。2015/03/15(日) 14:16:19.36
ミス
grep -o 'aaa[0-9\.][0-9\.]*' | sed 's/aaa//g' | tr '\n' ' '
0451名無しさん@お腹いっぱい。2015/03/15(日) 14:37:30.13
>>447

grep -Po '(?<=aaa)\d+(\.\d+)?(?=[^\d.]|$)'
0452名無しさん@お腹いっぱい。2015/03/15(日) 14:52:31.67
>>447
>>449
>>450
再度ありがとうございました。
私のファイルのケースですと450さんのやり方で完全にできました!
大変助かりましたし、勉強になりました。ありがとうございました。


>>448
本当そうしようと思います。
それ以前にgrepやsedは簡単な文字抜き出しぐらいにしか使ったことがなかったのですが、
こんなに便利だとは驚きました。学習して次は自分で解決できるようにしたいと思います
04534482015/03/15(日) 14:55:28.70
これは私見だが
grepの-PはPerlの正規表現として扱うためのオプションだ
Perlを知ってるなら問題ないが、知らないなら>>450のが多分勉強対象としては正しい
0454名無しさん@お腹いっぱい。2015/03/15(日) 15:09:05.03
>>451
投稿した後でレス確認しました。すいません。
こちらのやり方でもできました!ありがとうございました。
書き方の意味を勉強してみたいと思います。
>>453
ありがとうございます。perlも知らないので、
教えていただいたオプションの意味も含めて調べてみようと思います。
0455名無しさん@お腹いっぱい。2015/03/25(水) 06:56:05.87
専用コマンド使わずに実用的な強度の暗号復号フィルタとか誰か書ける?
0456名無しさん@お腹いっぱい。2015/03/25(水) 12:51:41.84
>>455
専用コマンドってのは、gpg とか openssl みたいなのを指してるの?
python とか perl とかを使っていいのならライブラリ次第で何とでもなりそうだけど、
それも NG なのかな?
0457名無しさん@お腹いっぱい。2015/03/25(水) 15:07:14.94
rot13でよければ
tr A-Za-z N-ZA-Mn-za-m
0458名無しさん@お腹いっぱい。2015/03/25(水) 18:11:12.12
それはさすがに「実用的な強度」とは言えないのでは……
0459名無しさん@お腹いっぱい。2015/03/27(金) 22:26:36.44
会社でシェルスクリプト(awkやsed)いじる必要があるんですが
何かおすすめの本ないですか?
0460名無しさん@お腹いっぱい。2015/03/28(土) 00:47:40.73
ttp://www.goggle.co.jp/
0461名無しさん@お腹いっぱい。2015/03/28(土) 11:31:55.66
後ろからn文字目のみを削除する方法ってある?

1234567890
なら
123456780

12345
なら
1235

になるような。
0462名無しさん@お腹いっぱい。2015/03/28(土) 14:36:27.39
sed -e 's/.\(.\{n-1\}\)$/\1/'
後ろから2文字目なら
echo 12345 | sed -e 's/.\(.\{1\}\)$/\1/'
1235
■ このスレッドは過去ログ倉庫に格納されています