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

レス数が1000を超えています。これ以上書き込みはできません。
2020/08/21(金) 15:17:55.64ID:mArnj/tT
シェルスクリプトに関する総合スレッドです。

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

シェルスクリプト総合 その33
https://mevius.5ch.net/test/read.cgi/tech/1584893550/
2020/11/16(月) 20:09:53.39ID:Ks5/uhC8
>>920
変数展開とか置換で使いやすいからやろ。
意義ならそれで充分。
2020/11/16(月) 21:47:14.87ID:was5dDeL
>>922
変数展開とかするならシェル変数で十分じゃん
環境変数にする必要がない
2020/11/16(月) 21:47:38.57ID:VPqCGhU1
readコマンドと同じようなことを,変数を新たに生成することなく実現する方法ないかな。
当然,入力結果は変数に格納せずに,そのまま標準出力に返す。
(←べつにこの仕様じゃなきゃいけない訳じゃないけど,変数なしだとこれくらいしかないかな?)

例えば引数を付けないcatだと近い挙動を実現できるけど,
入力を終了する時に<Enter>じゃなくて<C-D>を入力しないといけないので,
利用者側の操作が違ってきちゃう。
↑このあたり,sttyとかで設定できないかな〜と思いつつも,
stty eof ^Jとかしても無理なんで詰まっている。
2020/11/16(月) 21:56:03.84ID:was5dDeL
変数を新たに生成しないなら、決め打ちのグローバル変数を使ったら?
それも嫌ならPS1とかPS2を使うとかw
どうせシェルスクリプトの中では使わないだろうし
2020/11/16(月) 22:19:15.08ID:was5dDeL
お、思いついたw

read workとやってwork変数を使う

だけどそうすると上書きされちゃうから
set -- "$work"として$1にバックアップしておく
そいでecho "$work"してから$1を$workに戻す

ただしwork変数はread前に定義されてない可能性があるから
そこは変数が定義されてるかどうかで処理を分ける(めんどくさいから任せたw)

これで一時的には変数を使うけど使うけど最終的に副作用はない
2020/11/16(月) 22:20:25.71ID:was5dDeL
この方法を使えばreadの結果を$1とかに入れることもできそうw
2020/11/16(月) 23:22:53.16ID:9mrX0/C/
>>924
単にサブシェルにするのでは駄目?
( read a; echo "$a" ) みたいに
2020/11/16(月) 23:44:35.69ID:VPqCGhU1
>>926
sttyとか使ってなるべく代入を減らそうとしてたんだけど,
この方法でも「変数を節約する(使わない)」という目的は
普通に達成できるな。
ありがとう。
2020/11/17(火) 09:06:13.86ID:iIrFjUs6
Macは昔は:がフォルダの区切り文字だったんだよな
ファイルのリソース情報が本体ファイルと別になってて2個1だった
2020/11/17(火) 10:59:29.50ID:BpUAWx5v
>>921
macOSのファイルシステムはユニコードで規定されているのでそういうチェックも
あるというか。
ま、ある意味文字列の中身を厳密に規定しないできた流れのFSと、
ユニコードの普及を推進していた(る)会社が作ったFSの違いかな?
2020/11/17(火) 16:59:32.69ID:RPD3bx3d
ちなみにWindows 10ではクソみたいな方法で,*一見すると*コロンや不等号を
ファイルに名付けられるような仕様になっている。

https://youtu.be/vE8jL9Fz9h0

誰得なのこの機能?
2020/11/17(火) 17:09:47.51ID:nHdTOcnh
>>932
誰得もなにも動画のとおりだろ

NTFSではPOSIX対応が必要だったため、本来はコロンとかを
ファイル名に入れられるんだがWindowsでは互換性のために禁止されてる

しかしWSLの登場でコロンや不等号のファイル名に対応する必要が出てきた
誰得ってのはこのWSLユーザーに決まってる
NTFSではこれらの文字を使おうと思えば使えるのだが、それだと相互運用で問題が出る

だからWSLでコロン等をファイル名に使ったら、Unicodeの特殊な文字に名前を変更して記録している
そしてこの仕様はもともとCygwinで考え出されたものだ

WindowsでLinux的に使おうとすれば、どうしてもそういう文字に対応する必要があるので
Cygwinで考え出された仕組みをWSLでそのまま取り入れてるだけ
2020/11/17(火) 17:55:26.97ID:WUYxAqUP
>>933
勉強になった。
よっ、生き字引!
2020/11/17(火) 18:03:09.09ID:nHdTOcnh
普通にcygwinで:というファイル名を作ったら
Windowsからはどう見えるんだ?って調べればわかることだな
もう何年も前の話だよ
俺にとってはWSLでも同じでワロタ状態
2020/11/17(火) 18:05:47.61ID:nHdTOcnh
あとwslpathコマンドも、昔からCygwinにcygpathというコマンドがあるのを知っていれば
同じような仕組みにしたのねって思うはず
MS独自の仕組みじゃなくて既存の仕組みを流用する当たり
今のMSがオープン的な考えになってることがよく分かる
937デフォルトの名無しさん
垢版 |
2020/11/17(火) 18:34:05.16ID:J3+TnR7G
全角文字使えは解決するのにな
2020/11/17(火) 18:44:18.62ID:8pwQehN5
全角と半角を同一視したらダメだろ
だから通常使われてない文字にわざわざしてるんだが
939デフォルトの名無しさん
垢版 |
2020/11/17(火) 19:02:58.91ID:J3+TnR7G
ファイル履歴「せやな…」
2020/11/17(火) 20:36:01.00ID:RPD3bx3d
wslpathがcygpathと同じ仕組みなのってなんで分かったん?
いや,つっかかる訳じゃなくて,
wslpathってソース公開されてないからさ。
941デフォルトの名無しさん
垢版 |
2020/11/17(火) 20:46:02.57ID:/MJ+K6rY
a.txt
a x Nov 17 2020 aaa
b x Nov 18 2020 bbb
c z Nov 19 2020 ccc

cat a.txt | awk -v hy="-" '{if("$2"=="x"){"date -d "$3hy$4hy$5" ¥"+%Y-%M-%D¥" | getline var ; print $1","var","$6}}'

これ実行するとvarの内容がたまに前の行の値のままになったりするんだけど
|が悪いの?


結局 while IFS=' ' read 〜に変えたらやりたいことはできたけと何故上手くいかなかったのか分からなくて
2020/11/17(火) 21:02:17.75ID:8pwQehN5
>>940
コロンとかのファイル名の話な(これはwslpathやcygpathとは関係ない)

cygwin「cygwin環境でHOME以下に作ったファイルはC:\cygwin64\home以下に作るで」
cygwin「 cygwin環境で : とか * という名前のファイル作れるで」

10年前の俺「え?なんで?エクスプローラーから見たら文字化けしとるやんけwww なんだこりゃ」
数分後 → 「ふーん」

WSL「/mnt/c/Users以下に作ったファイルはC:\Users以下に作るで」
WSL「WSL環境で : とか * という名前のファイル作れるで」

俺「エクスプローラーから見たら文字化けしとるやんけwww 既視感ぱねぇwww」
数分後 → 「同じじゃねーかwww」


wslpathは別にcygpath使ってればコマンド名とかオプションとか真似してるってわかるだろ?
WSL(Linux)にパスを変換するときのオプションが何故か-uな所とか
(cygwinでは-uの長いオプション名は--unix)
2020/11/17(火) 21:04:26.43ID:8pwQehN5
まあもしかしたらcygwinよりも前にSFU(の前身)とかがやってたのかもしれんけどさ
2020/11/17(火) 21:32:09.28ID:yKNV/xx9
>>940
「仕組み」は、具体的な実装のことではなく、全体的なやりかたのことやろ。
2020/11/17(火) 22:11:55.77ID:8pwQehN5
> 俺「エクスプローラーから見たら文字化けしとるやんけwww 既視感ぱねぇwww」
> 数分後 → 「同じじゃねーかwww」

この同じじゃねーかwwwっていうのは : などのWindowsでは使えない文字のマッピング先の文字コードの話ね
そういや文字コードが同じであることは確かめたけど、実際にcygwinで作ったファイルをWSLで見たことなかったわ
んで、今やってみたけど、当然なんだけど、cygwinで作った : というファイルはWSLでちゃんと : になってたw
cygwin(たぶんmsysも同じ)との相互運用も考えてこうしたんだろうな
2020/11/18(水) 14:43:02.92ID:oGkGNlvA
>>941
>"date
" がいらない

>\"+%Y-%M-%D\"
2つの\ がいらない

これを実行しても、何も表示されないけど。
なんで?
947946
垢版 |
2020/11/18(水) 14:47:49.14ID:oGkGNlvA
>>941
>\"+%Y-%M-%D\"

ひょっとして、この\ は、キーボードのバックスラッシュじゃないのかも?
ちゃんとキーボードで、入力してみれば?
948946
垢版 |
2020/11/18(水) 14:58:29.15ID:oGkGNlvA
>>941
Ruby で、CSV なら、

require 'csv'

CSV.foreach( "a.csv", col_sep: " " ) do |row| # 1行ずつ処理する
p row[ 1 ]
end

出力
"x"
"x"
"z"
949デフォルトの名無しさん
垢版 |
2020/11/18(水) 15:28:33.58ID:XsHXPiSN
>>946
>>947
すまんスマホで打ったので間違ってた

cat a.txt | awk -v hy="-" '{if($2=="x"){"date -d "$3hy$4hy$5" +%Y-%m-%d" | getline var ; print $1","var","$6}}'


+%Y-%m-%dは¥(バックスラッシュ)"で囲まなくてもOKだった
出力が3行以上あると>>941の現象になる気がする
950946
垢版 |
2020/11/18(水) 15:35:10.65ID:oGkGNlvA
>>949
なら、下のように出力された

a,2020-11-17,aaa
b,2020-11-18,bbb
951デフォルトの名無しさん
垢版 |
2020/11/18(水) 15:59:00.88ID:XsHXPiSN
>>950
出力される行数10行くらいに増やした場合は?(もちろん全て日付変えて)
952946
垢版 |
2020/11/18(水) 16:43:39.93ID:oGkGNlvA
正しく出力される。
実際には、c, d, f などは出力されていないけど

a,2020-11-17,aaa
b,2020-11-18,bbb
c
d
e,2020-11-21,eee
f
g,2020-11-23,ggg
h,2020-11-24,hhh
i
j,2020-11-26,jjj
k,2020-11-27,kkk
l,2020-11-28,lll
m
n
o,2020-12-01,ooo
p,2020-12-02,ppp
q,2020-12-03,qqq
r
s,2020-12-05,sss
t,2020-12-06,ttt
u
953デフォルトの名無しさん
垢版 |
2020/11/18(水) 17:46:13.72ID:XsHXPiSN
>>952
ありがとう

何故だろう
2020/11/18(水) 22:39:32.53ID:c4VI5UKm
フィールド数が想定がところがあるとエラーで getline が呼ばれなくて
var がそのままになったりするのかも?
2020/11/18(水) 22:40:20.82ID:c4VI5UKm
想定が -> 想定外な
956デフォルトの名無しさん
垢版 |
2020/11/18(水) 23:00:38.15ID:XsHXPiSN
>>954
これかも
1列目にブランク入りのデータが入ってた
2020/11/18(水) 23:22:35.65ID:2l0B+GoX
AWKのgetlineってめっちゃ便利よね。
これ使い始めたらもうシェルスクリプトじゃなくてAWKスクリプトになるけどw
958デフォルトの名無しさん
垢版 |
2020/11/18(水) 23:25:59.76ID:XsHXPiSN
>>956
いや違うわ
ブランク入ってたらそもそも$2がxにならない
2020/11/19(木) 02:55:11.75ID:kL0AGIHT
まず再現するデータをよこせ
2020/11/19(木) 07:48:43.53ID:jemYGepS
元ネタの人じゃないけど以下のデータでおかしくなった。

a.txt
a x Nov 17 2020 aaa
b x Nov 18 2020 bbb
c x Nov 18 2020 ccc
d x Nov 19 2020 ddd
d x
e x Nov 19 2020 eee
f x Nov 20 2020 fff

d の行以降の日付が今日の日付になった。Ubuntu 16.04.7。
なんかデータをちょっといじると再現しなくなるような感もある。
961946
垢版 |
2020/11/19(木) 10:41:14.25ID:uVXRNBYq
>>960
d x
という変な行も、データに入れるのか?

Windows 10, WSL2, Ubuntu 18.04 では、下のように出力された

a,2020-11-17,aaa
b,2020-11-18,bbb
c,2020-11-18,ccc
d,2020-11-19,ddd
d,2020-11-19,
e,2020-11-19,eee
f,2020-11-20,fff
2020/11/19(木) 21:37:07.41ID:ACSoydf1
>>961
そう。わざと壊れたデータで遊んでみているw

確実に再現できるバグは、ある意味治すのは易しい。
再現方法がよくわからんバグは...どうしたら再現するかを考えるのも一興かとw


あしまった、データが違ったかも。こうかな。

a x Nov 17 2020 aaa
b x Nov 18 2020 bbb
c x Nov 18 2020 ccc
d x Nov 20 2020 ddd
d x
e x Nov 20 2020 eee
f x Nov 20 2020 fff
2020/11/19(木) 21:49:05.89ID:pLwLwTYy
ちなみにdateコマンドは日付が空だと今日の日付を入れるようなので
Nov 20になる前に試すのがおすすめw
964946
垢版 |
2020/11/20(金) 02:15:19.68ID:pwTm9Uxw
このデータでやった。
b が今日の日付になる

a x Nov 03 2020 aaa
b x
c x Nov 05 2020 ccc
d x Nov 06 2020 ddd

出力
a,2020-11-03,aaa
b,2020-11-20,
c,2020-11-05,ccc
d,2020-11-06,ddd
2020/11/20(金) 14:19:37.94ID:EGUOn9wt
>>964
うん、それは単に >ちなみにdateコマンドは日付が空だと今日の日付を入れるようなので
だと思う。

自分の環境で >>962のデータを食わせたら
a,2020-11-17,aaa
b,2020-11-18,bbb
c,2020-11-18,ccc
d,2020-11-20,ddd
d,2020-11-19,
e,2020-11-19,eee
f,2020-11-19,fff

となった。e, f で空のdの所で得た日付を使われている感じ。ちょっとおもしろい。
966デフォルトの名無しさん
垢版 |
2020/11/23(月) 08:04:11.39ID:bkMAXdue
ループ処理をバックグラウンドで流すと500個ぐらいプロセスができて
まったく動かない。いい方法ないかな。
2020/11/23(月) 08:50:42.89ID:eEk7O1Jq
>>966
500並列処理でもしてるんか?
そりゃ普通のCPUじゃ無理だろうよw
制限でもしろ
2020/11/23(月) 10:20:31.35ID:QFnswc7I
>>966
シェルの問題なんだろうか…?
2020/11/23(月) 11:57:26.98ID:fPgs5Hol
10万行のループ処理にかかる時間は、while は5秒、for は9分。
それらを、awk, perl に書き直せば、0.1秒

forの時間のほとんどは、プロセスの起動・終了処理。
そもそも、bash はループ処理に向いていないので、dash を使う。
それでも、シェルスクリプトはループ処理に向いていない

awk, perl, Ruby などは、1プロセス内で処理するから、
シェルスクリプトよりも断然速い
2020/11/23(月) 12:55:10.05ID:eEk7O1Jq
古いCorei7だけどbashで0.5秒で終わるぞ?

$ time -p bash -c 'i=0; while [ $i -lt 100000 ]; do i=$((i+1)); done'
real 0.53
user 0.51
sys 0.00

dashなら0.15秒だな
$ time -p dash -c 'i=0; while [ $i -lt 100000 ]; do i=$((i+1)); done'
real 0.15
user 0.14
sys 0.01
2020/11/23(月) 12:58:14.53ID:eEk7O1Jq
> forの時間のほとんどは、プロセスの起動・終了処理。

forでプロセス起動なんてしないけど?
2020/11/23(月) 13:16:27.49ID:LSu3Ppxv
>>968
どう見てもそういうシェルスクリプトを書いたとしか見えんな
バックグランドプロセスを自分で管理するのがめんどくさいとかだったら、なんか上の方のレスであったな
2020/11/23(月) 13:22:54.01ID:LSu3Ppxv
GNU Parallel か

>>966
GNU Parallel で簡単に解決できそ
974969
垢版 |
2020/11/23(月) 13:37:45.01ID:fPgs5Hol
>>970
漏れは、6年前のパソコン工房の初心者向けノートPC、
Windows 10 Home, 64 bit, 20H2(2020 秋)
WSL2, Ubuntu 18.04

CPU は、i3-3120M。2 core, 4 thread のエコモード。
8GB メモリで、

bash
real 1.53
user 1.53
sys 0.00

dash
real 0.42
user 0.42
sys 0.00
975968
垢版 |
2020/11/23(月) 14:12:23.68ID:QFnswc7I
>>970
$ time -p bash -c 'i=0; while [ $i -lt 100000 ]; do i=$((i+1)); done'
real 0.30
user 0.30
sys 0.00
$ time -p dash -c 'i=0; while [ $i -lt 100000 ]; do i=$((i+1)); done'
real 0.11
user 0.11
sys 0.00

OS: Gentoo via WSL2 on Windows 10 (build 20262.1010)
CPU: AMD Ryzen 7 3700X
RAM: 16 GiB, 2666 MHz
976968
垢版 |
2020/11/23(月) 14:12:52.26ID:QFnswc7I
多分ね,遅いのはシェルのせいじゃない。
組み方がおかしい。
2020/11/23(月) 16:34:44.84ID:iaIJT3SX
テキストファイルの中にカレントディレクトリを基準にしたファイルリストがあります。
このテキストファイルのファイルリストのファイルを~/backap/以下にディレクトリ構造を
維持したままコピーする方法を教えてください。

ファイルリストに含まれるパスは全てファイルです。ディレクトリで終わるパスは含まれません。

./file/jidori.jpg
./nikki/2020/11/01.txt
↑こんな感じのがたくさんあります
2020/11/23(月) 17:18:30.33ID:nsFhHMUZ
$ rsync -a ―files-from=./file_list.txt . ~/backap
2020/11/23(月) 18:16:32.54ID:hekS2Nxq
$ cp -pr ./* ~/backup

ではいかんのか?
2020/11/23(月) 20:09:16.39ID:QFnswc7I
ちなみにbackapじゃなくてbackupな
2020/11/23(月) 20:59:12.22ID:bsUMpvvq
>>979
あほ?
982デフォルトの名無しさん
垢版 |
2020/11/24(火) 07:52:34.13ID:4nyZROoo
rsync -avをよく使う
983977
垢版 |
2020/11/24(火) 18:17:20.50ID:xCsiFrs4
大変助かりました!ありがとうございます!!
2020/11/24(火) 20:21:52.33ID:mbTiTj6s
次スレそろそろ……
2020/11/24(火) 21:38:15.89ID:mbTiTj6s
言い出しっぺなんで建てました。
https://mevius.5ch.net/test/read.cgi/tech/1606221440
2020/11/24(火) 23:19:57.68ID:EBaS3Lgi
しっぺ
デコピン
馬場チョップ
2020/11/25(水) 00:18:39.96ID:jf5n46hh
しっぷ
デブちょん
バカちょんぷ
2020/12/10(木) 10:37:09.61ID:/AM+Meb9
(´・ω・`)
2020/12/10(木) 14:19:01.84ID:/AM+Meb9
(´・ω・`)
990デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:55:47.30ID:8Z169BTH
うめ!!!
991デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:55:56.82ID:8Z169BTH
うめっ11
992デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:56:03.69ID:8Z169BTH
うめあ
993デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:56:11.79ID:8Z169BTH
うめい
994デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:56:19.82ID:8Z169BTH
うめうえ
995デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:56:26.45ID:8Z169BTH
うめえ
996デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:56:36.33ID:8Z169BTH
うめめt
997デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:56:45.14ID:8Z169BTH
ume
998デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:56:52.52ID:8Z169BTH
umeru
999デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:57:00.61ID:8Z169BTH
uue
1000デフォルトの名無しさん
垢版 |
2020/12/11(金) 08:57:08.73ID:8Z169BTH
ume
10011001
垢版 |
Over 1000Thread
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 111日 17時間 39分 13秒
レス数が1000を超えています。これ以上書き込みはできません。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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