シェルスクリプト総合 その32

■ このスレッドは過去ログ倉庫に格納されています
2019/10/25(金) 00:08:45.53ID:6btPTvif
シェルスクリプトに関する総合スレッドです。

全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。
・「○○(他の言語)でいいやん」は禁止。他のスレに行ってください。

シェルスクリプト総合 その31
https://mevius.5ch.net/test/read.cgi/tech/1565446670/
83デフォルトの名無しさん
垢版 |
2019/11/28(木) 08:09:55.57ID:f/6vs/+B
trap '
for ((aa = 0; aa < MAX_TIMER; aa++)); do
if [ ${tim_flg[$aa]} -eq 1 ]; then
if [ ${tim[$aa]} -gt 0 ]; then
tim[$aa]=$((tim[$aa] - 1));
fi
fi
done
printf "%3d" ${tim[*]};
echo ":" $(date -R);
' SIGINT
84デフォルトの名無しさん
垢版 |
2019/11/28(木) 08:11:04.34ID:f/6vs/+B
for((nn=0; nn < 10; nn++)); do
tim_flg[$nn]=1;
done

while true; do
for((nn=0; nn < 10; nn++)); do
if [ ${tim[$nn]} -eq 0 ]; then tim[$nn]=$((nn + 2)); fi
done

sleep 0.6
done;
終わり
2019/11/28(木) 08:24:45.92ID:uZo2jF8i
なんか動いてるけど、何やってるのかわからんなw
とりあえずCTRL+Cで停止しなかった。
86デフォルトの名無しさん
垢版 |
2019/11/28(木) 08:29:37.54ID:f/6vs/+B
動作を確認するためタイマーのカウントとセットを繰り返しています。
終了するためにはSIGKILLを与えてください。
2019/11/28(木) 08:30:36.19ID:uZo2jF8i
しばし読んでみたけど、やっぱりわからんw

これ指定したn秒ごとにシグナル送るんじゃないのか?
tim配列とかtim_flgの意味がさっぱりだ
2019/11/28(木) 08:41:39.82ID:uZo2jF8i
簡単な所から。まずシグナルはSIGはいらんぞ。
bash限定ならそれでもいいがPOSIX的には無いほうが正しい。
INTはCTRL-Cなので、USR1またはUSR2、もしくはSIGHUPとかの方が良い。
セミコロンはC言語じゃないんだから行を継続しないときにはつけないのが一般的
89デフォルトの名無しさん
垢版 |
2019/11/28(木) 08:42:09.42ID:f/6vs/+B
各タイマが0になったらなんかをちょっとやり、またタイマをセットするというプログラムです

tim配列はタイマ本体です。tim_flg配列はタイマ使用/不使用のフラグです。
2019/11/28(木) 08:49:25.10ID:uZo2jF8i
やっと理解したが、これ説明なしに理解するの大変だぞw
本質的じゃないコードが複雑でそっちのほうが多すぎる。
2019/11/28(木) 08:51:32.36ID:uZo2jF8i
tim_flgの意味がないな。いや意図は想像できる。(というか>>89に書いてあるか)
サンプルとしてはノイズにしかなってないので理解ができない。
2019/11/28(木) 21:14:01.96ID:uBUVzLWV
宿題の添削をしてやるとか親切たなw
2019/11/28(木) 21:36:47.47ID:asJppHFe
目的は、bash依存すんな。って言うことだったんだがなw
流石にbash依存してる部分が、本質的じゃない所ばかりだとやる気が。
バッサリ削ったら簡単に、bash依存なくせるんでどうしようかなと思いながらレス待ちw
2019/11/28(木) 23:49:59.71ID:RaRUIeaw
bash依存しまくりで
https://wandbox.org/permlink/EHSiHk726Bn4qvVO
95デフォルトの名無しさん
垢版 |
2019/11/29(金) 00:53:33.34ID:Fh79+8D6
あんまりソフトタイマに有用性を感じてもらえないようで残念でした。
2019/11/29(金) 01:09:45.97ID:IIqk2+5U
timeoutでやっつけ
2019/11/29(金) 02:19:44.34ID:XcyRQJ1W
>>95
タイマに有用性がないんじゃなくて
君が作ったスクリプトに有用性がなかったんだよ
2019/11/29(金) 04:30:20.91ID:9RHOSbKH
>>94
めんどくせーから、もうそれでいいやw

その程度でbash依存するな
https://wandbox.org/permlink/Uh4eQX682YzoK8rn
2019/11/29(金) 05:10:07.47ID:hA38q2SN
おれおれかよ
100デフォルトの名無しさん
垢版 |
2019/11/30(土) 00:04:41.28ID:FMRNVBPU
Wgetであるサイトの特定のディレクトリ配下の特定のファイルを
ダウンロードしたくて下記のコマンドを書いてもルートのindex.html
しかダウンロードしてくれません。

これは何がまずいのでしょうか?

wget -r -A Download拡張子 -I /Downloadディレクトリ URL
2019/11/30(土) 00:53:41.92ID:KUL76oc2
オプションに -e robots=off -U mozilla でも付けてみたら上手く行くかも
2019/11/30(土) 00:54:25.61ID:czFcPKLy
碌に調べずの返答でアレなんだが多分訪問先のサイトがファイル一覧
を返すのを禁止してる(apache httpd だと Indexes オプションが有効
になってない)からだと思う
103デフォルトの名無しさん
垢版 |
2019/11/30(土) 13:20:31.41ID:f33nsdyy
リファラの偽装が必要かも。知らんけど
2019/11/30(土) 16:49:40.30ID:mvBIEviw
googleはbashがデフォルト
2019/12/01(日) 11:47:31.42ID:0pH8jk7+
bash/zsh依存しまくりで
https://wandbox.org/permlink/moif346imXqiuDxD

そんなのが仮に必要でも
trap 'date -R' USR1

for (( i=1 ; i <= 10 ; i++ )); do
( sleep $i; kill -USR1 $$ ) &
done

wait
でいいだろとしか思わんけどw
106デフォルトの名無しさん
垢版 |
2019/12/01(日) 19:22:22.28ID:IoGKXgrY
>>91
tim_flgをゴミ扱いしたこいつがソフトタイマを理解していない。
2019/12/01(日) 19:49:41.33ID:YWi4MX0G
このサンプルでは1固定なんだからゴミやろ
2019/12/02(月) 22:02:29.21ID:9nn8K+iP
親ディレクトリ
-子ディレ クトリ(1)
 file(1).txt
 file ().txt
-子デ ィレクトリ(2)
 file(2) .txt
-子ディレクトリ(3)
 fil e(3).txt

ディレクトリとファイル名の半角スペースと半角の()を_で置換したいのですが
どうやればいいのでしょうか
for dir in $(ls -d */); do
for f in ${dir}*; do
mv "$f" `echo $f|sed -e 's/[ ()]/_/g'`
done
done
これでディレクトリ名とファイル名はどうにかなったのですが、、
一回目ではディレクトリ名が変換されてしまうのでファイル名が変換されず
対応策として同じコードを2回実行してファイル名も変換しています
まず一回目にディレクトリ名を変換するために
for dir in $(ls -d */); do
mv "$dir" `echo $dir|sed -e 's/[ ()]/_/g'`
done
をやってみたのですが、statがなんやらと警告が出てきます
2019/12/02(月) 22:13:56.47ID:cDa5fVnx
そういう用途なら、forとかlsとか使わないでfind使え
2019/12/02(月) 22:15:41.19ID:cDa5fVnx
いきなりstatがでるような事はやめて、
echo mv なんとか かんとか で実行命令を表示するようにしろ
怖すぎるわ。それやればなんとかなるだろ
2019/12/02(月) 22:19:56.11ID:agtAae1a
rename 関係はperlで試せる dry run 作ってる
https://pastebin.com/0uJ462jq
touch "file(1).txt"; ~/bin/rename.pl dry 'tr/[()]/_/' *txt
file(1).txt => file_1_.txt

~/bin/rename.pl run 'tr/[()]/_/' *txt; ls
file_1_.txt
2019/12/02(月) 22:46:09.47ID:RT0MauQR
find . -name '*[ ()]*' -print | sort -r | while read item; do
mv "$item" "${item%/*}/$(echo "${item##*/}" | tr ' ()' '_')"
done
113デフォルトの名無しさん
垢版 |
2019/12/03(火) 07:24:55.79ID:v9g/lO5M
Ruby で作った。
コードは次のレスに書く

DryRun を使ったので実際には、変更されない

ファイル/ディレクトリは、同時に変更すると、バグるかも知れないので、別々に変更する。
また「子ディレクトリ(1)/孫ディレクトリ(1)」のように、2か所以上同時に変更すると、バグるかも知れない

こんな複雑なものを、シェルスクリプトで書くのは超危険!

特に移動は、dest が存在するときは移動になり、
存在しないときは変更になるという、極めて難しい場合分けが必要で、

処理の途中でエラーになると、エラーまでの処理が確定してしまうから、中途半端で巻き戻せないから、
必ず、親ディレクトリ以下のバックアップを取っておく!
114113
垢版 |
2019/12/03(火) 07:25:55.85ID:v9g/lO5M
require 'fileutils'

root_dir = "C:/Users/Owner/Documents/Ruby/test/**/*" # 基準ディレクトリ

# 変更前のファイル/ディレクトリを入れる配列
src_files = [ ]; src_dirs = [ ]

# 基準ディレクトリ以下のファイル/ディレクトリを取り出して、配列に入れる
Dir.glob( root_dir ) do |path|
case
when File.file?( path ) then src_files.push ( path )
when File.directory?( path ) then src_dirs.push ( path )
else # 処理しない
end
end

def change_paths( src_ary ) # ファイル/ディレクトリ名を変更する
src_ary.each do |src_path|
dest_path = src_path.tr( " ()", "_" ) # 変換
next if src_path == dest_path # 変換されなかった場合は、処理しない

# 変更後の名前のファイル/ディレクトリが、既に存在すれば、エラー
msg = "変更後の名前のファイル/ディレクトリが、既に存在します!\n#{ dest_path }"
raise msg if File.exist? ( dest_path )

FileUtils::DryRun.move( src_path, dest_path )
end
end

change_paths( src_dirs )
change_paths( src_files )
2019/12/03(火) 08:29:02.93ID:ujGDA/f+
なんかかえってめんどくさいことしてんな。perlでめんどくさく書きたいだけ?
2019/12/03(火) 08:29:47.31ID:ujGDA/f+
perlではなくrubyか。しつれい
117113
垢版 |
2019/12/03(火) 09:46:02.07ID:v9g/lO5M
mv を作った奴は、頭おかしいw

dest が存在するときは移動になり、
存在しないときは名前の変更になるという、極めて難しい場合分けが必要だから

漏れらが欲しいのは、
rename だけする関数と、移動するだけの関数の、2つに分かれている関数

それが分かれていないから、自分で処理を分けて、
かなりチェックしないと、バグってしまう
2019/12/03(火) 12:17:58.24ID:5ZiHQIvd
つまり自分に都合が悪い仕様=バグ
2019/12/03(火) 12:28:33.61ID:Uh1tIUQA
一括リネームってたいてい複雑になるから
GUIツールを使ったほうが良いと思うんだよね

Windows 10版のPowerToysにリネーム機能が追加
https://pc.watch.impress.co.jp/docs/news/1215602.html
2019/12/03(火) 18:09:42.76ID:+zVWCKlo
>>112
Fix(IFS文字が頭と末尾にある場合。dirname,basenameにしたのは気分)&Variation
find . -name '*[ ()]*' -print | sort -r | (IFS=''; while read item; do
mv "$item" "$(dirname "$item")/$(basename "$item" | tr ' ()' '_')"
done)


find . -name '*[ ()]*' -print | sort -r | (IFS=''; while read item; do
dir="$(dirname "$item")"; newname="$(basename "$item" | tr ' ()' '_')"; newpath="$dir/$newname"
[ ! -e "$newpath" ] && mv "$item" "$newpath" || echo "can't rename $item, exists $newname" >&2
done
# can't rename $item 〜 メッセージは単なる目安


find . -name '*[ ()]*' -print | sort -r | (IFS=''; while read item; do
dir="${item%/*}"; newname="$(tr ' ()' '_' <<< ${item##*/})"

[ -e "$dir/$newname" ] && {
name="${newname%.*}_"
ext="${newname#*.}"; [ "$ext" = "$newname" ] && ext='' || ext=".$ext"
while [ -e "$dir/$name$ext" ]; do
name+='_'
done
newname="$name$ext"
}

mv "$item" "$dir/$newname"
done)
2019/12/03(火) 18:14:03.14ID:+zVWCKlo
>>120
誤 ext="${newname#*.}"
正 ext="${newname##*.}"
2019/12/03(火) 18:30:56.19ID:HnkJN8FN
>>111
rename自体がperlだしちゃんと試行もあるけど
2019/12/03(火) 19:27:45.48ID:mUaHu9IR
>>122
perl ワンライナーより
dry run のスイッチと
どのように変更させるかに集中し
出力確認などの余計なことは共通する定型処理だから
コードにまとめたほうが使いやすい
2019/12/03(火) 19:44:49.63ID:R2wB6lmg
Linuxディストリによっては標準で入っている、perlスクリプトで作られたrenameコマンドのことだろ
2019/12/03(火) 20:48:36.39ID:jDo5c24e
renameは標準で入ってないとはいえ
テスト無しの自作コードでやるような処理じゃないやろ
find -depth -exec rename -nでdry-runしてから-n消せばいい
2019/12/03(火) 21:32:10.96ID:yTVXI633
話のネタから外れて何を主張したいのだか
2019/12/03(火) 22:25:15.93ID:yTVXI633
dry-runって言っても結局ひとつをrename/mvするその時点での状態でしか判断してないし、mvコマンドの前にecho付けるのと何が違うのだか
[ "$1" = "-n" ] && nac=echo || nac=''
$nac mv ...
でスイッチにしたけりゃ同じようにできるだろし
極めて難しいらしいことも結局時点での存在チェックしてるだけで、シェルスクリプトでtestを使うのと何がそうも極めて難しいほど違うのか

>>122
既に存在してたらエラー(オプションによって強行もできる)でもあるよね
The original C<rename> did not check for the existence of target filenames,
so had to be used with care. I hope I've fixed that (Robin Barker).
って、わざわざコメント書くようにな目玉なw
どのバージョンを使ってるのかわからんけど、パッケージによってはものすごいオプション拡張されたのが使われてるねえ
128113
垢版 |
2019/12/03(火) 23:09:51.48ID:v9g/lO5M
Windows10, WSL, Ubuntu 16.04 にも、/usr/bin/rename がある

この手の処理の何がヤバイかと言うと、

例えば、3つ目の処理で、エラーが出ると、
2つ目までは、変更されてしまっているから、
そこから再実行すると、最初から実行していた時と、初期条件が変わっている

データベースと同じで、一部分だけ更新されたような、中途半端な状態になってはいけない(一貫性)。
エラー時には、すべてをロールバックするべき。
または、全体のバックアップを取っておく

すべてを更新するか、すべてをロールバックするのどちらかの状態だけにする
2019/12/03(火) 23:14:22.94ID:50yNXJCt
自作コードがそれ以下なのになにを言っているのだか
2019/12/04(水) 00:03:09.04ID:LOcDYH/A
>>108
まだ見てくれてる? 変更するんじゃなくて新たに作るほうが無難だと思うよ。
新たに作るといっても通常ファイルはハードリンクできるからね。
実際にやってみたよ。

$ find a
a
a/a (0)
a/a (0)/a (00)
a/a (0)/a (01)
a/a (1)
a/a (1)/a (11)
a/a (1)/a (10)
$ find b
b
$ cd a
$ find * -type d | perl -ne 'chop; s/[ ()]/_/g ; mkdir("../b/$_") || die("$!:$_");'
$ find * -type f | perl -ne 'chop; $old = $_; s/[ ()]/_/g ; link( $old,"../b/$_") || die("$!:$_");'
$ cd ..
$ find b
b
b/a__1_
b/a__1_/a__10_
b/a__1_/a__11_
b/a__0_
b/a__0_/a__00_
b/a__0_/a__01_
$

途中で何か起こっても起こらなくても a の方は無傷だからね。好きなだけやり直せるよ。
2019/12/04(水) 02:51:13.25ID:hySlbdZs
pax -rwlpe src dst
2019/12/04(水) 23:27:09.69ID:xn8KyTI4
renameコマンドって複数ないか?
's/パターン/置換文字/' FILEとパターン 置換文字 FILEとサイトによって説明違うんだよな
俺が散らばったファイルをリネームする時はmoreutilsのvidir使ってるけど
テキストエディタで修正する奴な
2019/12/05(木) 00:34:07.65ID:0uggokQM
Larry Wall and Robin Barker版とそれの機能拡張版のAristotle Pagaltzis版じゃね
Aristotle Pagaltzisで増えた -s パターン 置換文字 FILE 使ってじゃないの
2019/12/05(木) 11:01:01.81ID:3XJjcX6a
>>132
util-linux版とperl同梱版(これはさらにいくつかに分かれる)の違い
debian/ubuntu なら前者rename.ul後者rename(Larry Wall版)
centos なら前者rename後者prename(Peder Stray版)
2019/12/05(木) 11:02:39.94ID:6ZFP3Xq2
>>132
Debian系はPerl付属のprename、
CentOS系はutil-linuxのrename.ulをrenameとして使ってるらしい
そら人によって言ってることが違う筈だ
2019/12/05(木) 15:05:31.16ID:0uggokQM
Larry Wall
- Robin Barker, 重複時実行しない、 重複時実行強制実行オプション
-- Aristotle Pagaltzis, 機能いろいろ (>>132 のはそのうちの -s/--subst from to じゃないの)
- Peder Stray, 重複時バックアップオプション
Aristotle Pagaltzis意外はそんなに変わらんかな。Aristotle Pagaltzisで追加した機能を使わなければAristotle Pagaltzisも

https://github.com/tldr-pages/tldr/issues/3125
Debian prename from pkg perl: Robin Barker & Larry Wall.
Debian/Ubuntu file-rename from pkg file-rename: Larry Wall.
Arch perl-rename from pkg perl-rename: Peder Stray (same as Fedora).
Fedora prename from pkg prename: Peder Stray (same as Arch).
macOS rename from pkg rename: Aristotle Pagaltzis.

らしいけど、Larry Wall版ってあるのか?Ubuntu は Larry Wall and Robin Barker だな
2019/12/05(木) 15:14:33.96ID:TzSLtKO4
たぶん基本的なことだと思うんですが、教えてください。

#!/bin/bash
echo -e \
'Hostname\tIP\tInterface\tVlan\tMode\tPort-Channel\tAllowed\sVlan\tDescription'\
> cp.tsv

このスクリプトを実行すると…

$cat cp.tsv
-e Hostname IP Interface Vlan Mode Port-Channel Allowed Vlan Description

このように、先頭に-eが入ってしまいます。なぜでしょう…?
2019/12/05(木) 15:19:51.21ID:0uggokQM
Perl同梱(?)のprename/file-renameがLarry Wall版か
Ubuntuで pkg rename (pkg file-rename??)を入れるとprename/file-renameもLarry Wall and Robin Barker版に上書きされる感じかな??
2019/12/05(木) 15:21:52.11ID:0uggokQM
>>138
いや、違った
Perl同梱(?)のprename/file-renameもLarry Wall and Robin Barker版か
2019/12/05(木) 15:22:44.42ID:WdOnkWYr
>>137

そのスクリプトを x.sh だとして、

$ /bin/sh x.sh

とかして実行したんじゃない?
2019/12/05(木) 15:55:06.05ID:Gb1I+/8K
>>137
-eをオプションとして扱うかどうかはシェルによって違う。
bashはオプションだが、dashはオプションではなくただの文字列
2019/12/05(木) 15:58:33.95ID:TzSLtKO4
>>140-141
あ、ほんとだ。
sh -xで実行してました。
bash -xだと大丈夫でした。
シェバン付けてるから大丈夫だと思い込んでました。ダメなんですね。
横着せずにきちんと打つようにします。

ありがとうございました!
143デフォルトの名無しさん
垢版 |
2019/12/06(金) 20:34:56.63ID:08yg4gJX
宇宙刑事シェバン
2019/12/10(火) 22:30:09.16ID:zD6aLrgM
x-y
↑こういう形式の,ハイフンで結ばれた二つの数字の計算結果の正負だけを知りたいのですが,
なるべく処理が早い方法ないですか。
対象の文字列は標準出力ではなくて変数に格納されています。

思い付いたのは
[ ${var%-*} -lt ${var#*-} ]

$((var < 0))
です。
どっちもPOSIXには準拠している筈ですが,同じような処理を大量に繰り返すとどうしても遅くなります。
これがシェルスクリプトの限界なら,仕方ないのですが,もう少し最適化できそうな気もします。
どうかお知恵とお力を貸してください。
2019/12/10(火) 23:18:51.56ID:kdXCWOtW
$((var < 0))はPOSIX準拠じゃなくね?

やるなら [ $(($var)) -lt 0 ] こうだろうけど
それでも遅いって言うならどうしようもないと思うが、
気になるほど遅いなら別のところに問題があるんじゃね?
2019/12/10(火) 23:24:09.60ID:kdXCWOtW
ちなみにうちのマシンだとこんな感じ

$ time sh -c 'var=1-2; i=0; while [ $i -lt 1000000 ]; do [ $(($var)) -lt 0 ]; i=$((i+1)); done'

real 0m2.722s
user 0m2.718s
sys 0m0.004s

100万やって3秒、1万回だと0.03秒。これが気になるとしたら
相当多くの数の計算をしてることになるはずなんだが本当に?
2019/12/10(火) 23:25:16.53ID:SL+fGedD
echo "$var<0"|bc
2019/12/10(火) 23:28:35.11ID:kdXCWOtW
bcプロセス起動してるから遅い
それは実行しなくてもわかる
2019/12/10(火) 23:50:31.02ID:kdXCWOtW
あとオマケ、速いとは思えないけど

IFS=-
var=1-2
set -- $var
echo $1 # 1
echo $2 # 2

これを使ってもできる。
速さは [ ${var%-*} -lt ${var#*-} ] とどっこいどっこいだろうな
もしかしたらset使ったほうが速いかもしれない程度
2019/12/10(火) 23:51:59.49ID:LOypIkS3
>>146
それ100万やったら50秒かかったわ
10万で5秒だしawk使うわ
2019/12/10(火) 23:59:28.15ID:kdXCWOtW
>>150
えらい遅いなw
俺のなんて2012年発売のCPUだぞ。
i7 3770。3.40Ghz(ブースト時で3.9Ghz)
2019/12/11(水) 00:00:32.26ID:ivhCTlPt
i7 3.4Ghzって今どき低スペックなのか?
ハイスペックかと思ってた
2019/12/11(水) 00:00:55.23ID:5YQOA1oq
>>150
awkつかうなら、awkのコード書いてみてくれ
実行してみる。
2019/12/11(水) 00:03:27.10ID:5YQOA1oq
>>152
スペックは低くはないと思うけどさ、もう古いし
中古だと2〜3万円台で搭載パソコンを買えちゃうよ
https://used.dospara.co.jp/sale/search.php?view=1&;kw=Core%20i7%203770&page=1
2019/12/11(水) 00:11:26.60ID:ivhCTlPt
>>154
凄い時代になったなw
いつのまにか皆さんハッピーになってた
2019/12/11(水) 00:15:38.57ID:rj8eSq0k
バックグラウンドで色々動きっぱなし(usage 60%ぐらい)のWindows PC(Ryzen 5 2600, 3.66GHz)で

Cygwin
real 0m23.706s
user 0m23.375s
sys 0m0.093s

WSL
real 0m3.987s
user 0m3.891s
sys 0m0.016s

だった。えっ、私のCygwin遅すぎ・・・
2019/12/11(水) 00:21:29.42ID:5YQOA1oq
>>156
うちもcygwinだとそんな感じだわw msysも
WSLは全然速度変わらないのにな

本質的にCPUだけで処理できる内容のはずだが
なにかシステムコール呼び出してるんだろうな
2019/12/11(水) 00:26:41.57ID:H3x5MOt+
>>153
$ printf "%d-%d¥n" $(shuf -r -i 0-999 -n 1000000) $(shuf -r -i 0-999 -n 1000000) > input.txt
$ time awk -F "-" '{ print (($1-$2) > 0) ? "+"$0 : " "$0 }' < input.txt > output.txt

1行目は0-999でランダムな引き算を100万件生成してファイル出力
2行目の処理は50秒かかったのと同じマシンで1.7~1.8秒で終わる

計算結果をキャッシュするからか10種類くらいの引き算の使い回しだと
100万件でも0.17秒くらいになる
2019/12/11(水) 00:40:07.88ID:5YQOA1oq
>>158
円文字化けしてんぞ

$ time awk -F "-" '{ print (($1-$2) > 0) ? "+"$0 : " "$0 }' < input.txt > output.txt

real 0m0.373s
user 0m0.300s
sys 0m0.005s

$ time sh -c 'while read var; do [ $(($var)) -gt 0 ] && echo "+$var" || echo " $var"; done' < input.txt > output2.txt

real 0m8.247s
user 0m4.337s
sys 0m3.904s

まあ速いんだろうけどさ。想定の範囲内かな。
2019/12/11(水) 00:40:26.36ID:H3x5MOt+
ランダムな引き算生成するawkバージョン

$ awk 'BEGIN{srand(); for (i=0; i<1000000; ++i) {print int(rand()*1000)"-"int(rand()*1000)}}' > input.txt
2019/12/11(水) 00:46:42.05ID:5YQOA1oq
お、こっちの方がわずかに速かった。スクリプトで計算させるよりも読み込み時に分割させたほうが良いんだろうな。
setを使って分割した場合は、setの呼び出しでコストがかかると思うけど

$ time sh -c 'IFS=-; while read i j; do [ $i -gt $j ] && echo "+$i-$j" || echo " $i-$j" ; done' < input.txt > output2.txt

real 0m7.866s
user 0m4.114s
sys 0m3.744s
2019/12/11(水) 00:53:02.45ID:mRJcWm57
$ time sh -c 'var=1-2; i=0; while [ $i -lt 1000000 ]; do [ $(($var)) -lt 0 ]; i=$((i+1)); done'
real 0m2.268s
user 0m2.264s
sys 0m0.004s

$ time { var=1-2; echo "i=0;while(i<=1000000){${var}<=0;i++;}" | bc > /dev/null; }
real 0m1.540s
user 0m1.175s
sys 0m0.366s
2019/12/11(水) 00:54:49.86ID:5YQOA1oq
> 対象の文字列は標準出力ではなくて変数に格納されています。

お前らこの条件忘れてるだろw
2019/12/11(水) 01:39:58.92ID:5YQOA1oq
うーん、よく考えるとこれ実際の要件を想定して
「それぞれのコマンドを使って処理をした結果を元に続きの処理をする」となると
差があまりなくなってしまうかもしれん

$ time sh -c 'while read var; do echo $(($var)); done' < input.txt | while read i; do [ $i -lt 0 ]; done

real 0m7.678s
user 0m9.059s
sys 0m4.427s

$ time awk -F "-" '{ print $1-$2 }' < input.txt | while read i; do [ $i -lt 0 ]; done

real 0m7.629s
user 0m6.358s
sys 0m1.580s

$ time bc < input.txt | while read i; do [ $i -lt 0 ]; done

real 0m7.649s
user 0m6.869s
sys 0m2.006s
2019/12/11(水) 01:44:25.40ID:5YQOA1oq
$ time sh -c 'while read var; do [ $(($var)) -gt 0 ] && echo + || echo; done' < input.txt | while read i; do [ "$i" ]; done

real 0m7.596s
user 0m9.484s
sys 0m5.123s

$ time awk -F "-" '{ print (($1-$2) > 0) ? "+" : "" }' < input.txt | while read i; do [ "$i" ]; done

real 0m5.418s
user 0m4.670s
sys 0m1.012s
2019/12/11(水) 01:47:25.15ID:5YQOA1oq
結果をファイルに吐き出すだけなら良いんだけどね、
その結果をシェルスクリプトを使って処理する場合の話
2019/12/11(水) 03:39:07.57ID:MgOCMEvC
>>151
今年出た i5 9500
プロセッサー・ベース動作周波数 3.00 GHz
ターボ・ブースト利用時の最大周波数 4.40 GHz
あんまり変わらない気がする

シェルスクリプトなんかスレッド使わないだろうし
2019/12/11(水) 07:28:04.35ID:hRzITiR9
>>167
スレッドバリバリ使ってるぞw
| つかうと必然的にスレッドになるしな
2019/12/11(水) 08:22:26.35ID:6UY8oXji
>>145
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04
によると
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html#tag_17_01_02_01
の一覧の内,sizeof()函数,++及び--単項演算子,Selection・Interation・Jumpは実装しなくてよい
とあるから>はPOSIXの範疇だと思います。
2019/12/11(水) 12:44:26.62ID:MgOCMEvC
>>168
そりゃプロセスだろ
2019/12/11(水) 13:32:50.85ID:hRzITiR9
>>170
今はCPUの話だからハイパースレッディングのスレッドだろう
2019/12/11(水) 13:55:32.35ID:hRzITiR9
>>169
POSIX準拠じゃないのでは?と言ってるのは
$((var < 0)) のvarは数値限定ってところだよ
2019/12/11(水) 15:18:53.13ID:++mq81bA
>>171
> | つかうと
じゃないの。普通は子プロセスだろう
2019/12/11(水) 15:22:46.18ID:++mq81bA
プロセスが別のコアで動くとかか??
スレッドをハイパースレッディングのスレッドを指すなんて初めてみた
2019/12/11(水) 15:28:13.91ID:hRzITiR9
>>173
文句は>>167に言ってくれ。合わせただけ
2019/12/11(水) 15:29:58.09ID:hRzITiR9
>>174
普通にCPUの所に4コア8スレッドって書いてあるからさ
https://kakaku.com/pc/cpu/itemlist.aspx?pdf_se=22&;pdf_Spec306=4
2019/12/11(水) 15:39:31.82ID:++mq81bA
そこまで出されるとマジでスレッドという意味で使ってたんだな
OSも知らないスレッドだろう、OSから見てもただのコアだろう
2019/12/11(水) 15:46:36.17ID:hRzITiR9
>>167涙目www

でよろしいか?
俺に言うなって
2019/12/11(水) 15:55:15.40ID:++mq81bA
一行目なんて書かなきゃならないのね
>>167もそんなスレッドのことを言ってないだろうに。なんでかなw

プロセスじゃなくスレッドならプロセス起動する無駄時間がないとかそういう意味でのだろうし、そもそもスレッドはそういうために
元々のネタがプロセス起動にどれだけ食われてるのかという話だな、するなら
2019/12/11(水) 16:11:12.77ID:6UY8oXji
>>172
なるほど。確かに準拠してませんでした,すいません。
2019/12/11(水) 20:23:56.94ID:MgOCMEvC
>>175
いや、あってないから
勘弁してくれ
2019/12/12(木) 01:47:04.79ID:4Chv4WTd
>>181
シェルスクリプトでスレッドってどういう事?
スレッド使わなくてもコアは使うじゃん。
2019/12/12(木) 02:33:13.07ID:NtLqNRlV
>>182
なんでオレに聞くんだよ
シェルスクリプトはスレッド使わないって当然のこと言っただけじゃないか
なんで頭悪い奴が絡んでくるんだよ気持ち悪いな
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況