読むだけでちょっと賢くなる、架空のまとめスレ

【疑問】rm *.txt の * とか [a-c] とか、正規表現と同じやと思ってた。ワイルドカード(グロブ)【LPICレベル1】

16レスカテゴリ:Linux
1: 名無しさん

ls a?.txt とか rm [!a]* とか、書き方がいろいろある
grep の正規表現と同じ意味なん?

2: 名無しさん

前提のおさらい。cp・mv・rm などは引数に並べたファイルをまとめて扱える。ディレクトリのコピーと削除には -r を付ける

3: 名無しさん

>>1
似てるけど別物。ワイルドカードはシェルがファイル名に展開してからコマンドに渡す。コマンドは展開後の名前しか見てない

4: 名無しさん

>>3
記号の意味
* 0文字以上の任意の文字列
? 任意の1文字
[abc] 中のどれか1文字、[a-c] は範囲
[!a](bash では [^a] も)a 以外の1文字

5: 名無しさん

>>4
a1.txt a2.txt b1.txt ab.log c10.txt があるディレクトリで試した
echo a?.txt → a1.txt a2.txt
echo [ab]1.txt → a1.txt b1.txt
echo [!a]* → b1.txt c10.txt
echo c?.txt → c10.txt は2文字なので当たらず、c?.txt のまま出た

6: 名無しさん

>>5
当たるものがないと、パターンがそのまま渡るんか

7: 名無しさん

>>6
bash の既定ではそう。ls *.csv は *.csv という名前を探して No such file or directory になる。shopt -s nullglob にすると空になる

8: 名無しさん

>>4
正規表現の * は「直前の文字の0回以上」で、. が任意の1文字。グロブの * は単独で「何でも」。. はただの文字

9: 名無しさん

>>1
ドットで始まるファイルは?

10: 名無しさん

>>9
* や ? は先頭のドットに当たらない。.hidden を含めたいなら .* と明示する
この環境の bash では echo .* が .hidden だけやった。古い bash では . と .. まで入ることがあるから、rm -r .* みたいなのは危ない

11: 名無しさん

>>4
{a,b} もグロブ?

12: 名無しさん

>>11
それはブレース展開で、ファイルがなくても文字列を作る
echo {a,b,z}9.txt → a9.txt b9.txt z9.txt(そんなファイルはなくても出る)
echo file{1..3} → file1 file2 file3

13: 名無しさん

>>12
mkdir -p proj/{src,doc} で2つ作れるやつやな

14: 名無しさん

>>3
コマンドにパターンそのものを渡したいときは?

15: 名無しさん

>>14
クォートする。find . -name '*.txt' はクォートしないと、カレントに .txt があったときに先に展開されて条件が変わってしまう

16: 名無しさん

>>3
展開するのはシェルで、コマンドは結果を受け取るだけ、か。echo で先に確かめてから rm するわ

管理人のひとこと