かつてディレクトリ内のすべてのFILE.cファイルをFILE.outにコンパイルするシェルスクリプトがありました。
私はそれを失い、それを再作成しようとしており、次のようになりました。非常に似ていることを知っていますが、どこで間違っているのかわかりません。
#!/usr/bin/env bash
for i in 'ls *.c'
do
gcc -g3 -o3 $i -o {$i%.}.out
done
答え1
このコマンドを実行する必要はありませんls *.c
。 Bashは自動的にワイルドカードパターンを拡張します。したがって、本当に絶望的でMakefileを作成したくない場合は、次のようにすることができます。
#!/usr/bin/env bash
for i in *.c
do
echo "gcc -g3 -o3 $i -o ${i%.c}.out"
# gcc -g3 -o3 "$i" -o "${i%.c}.out"
done
はい
次のサンプルデータがあるとします。
$ ls -1
a.c
b.c
c.bash
c.c
d.c
e.c
私のスクリプトを実行してくださいc.bash
。
$ ./c.bash
gcc -g3 -o3 a.c -o a.out
gcc -g3 -o3 b.c -o b.out
gcc -g3 -o3 c.c -o c.out
gcc -g3 -o3 d.c -o d.out
gcc -g3 -o3 e.c -o e.out
スクリプトを実行するには、echo
上記の行をコメントアウトしてから、このgcc
行のコメントを削除する必要があります。
答え2
あなたの質問を具体的に見ると、「どこで間違っているか」がパラメータ拡張にあるようです。ここで、出力ファイルに名前を付けるときにi値を変更しようとしているようです。
{$i%.}
ドル記号を間違って見たと思います。おそらく次の意味です。
${i%.}
正直に言うと、元のファイル名から「.」だけが削除されます。そして、「filename.c」は「filenamec.out」を生成します。次のことができます。
${i%.*}
これにより「filename.out」が生成されます。このパラメータ拡張構文は、「.」で始まるすべての項目を無欲なく削除することに変換されます。後。貪欲な削除の場合、構文は次のとおりです。
${i%%.*}
これがあなたのコードに関連し、あなたの質問に良い答えになることを願っています。
答え3
forループは、目的の出力コマンドではなくfor i in 'ls *.c'
文字列 ""を繰り返します。これはls *.c
コマンド置換演算子(たとえば)を使用して解決できますが、slmが指摘したようにfor i in $(ls *.c); do...
彼の答えにforループでシェルワイルドカードの出力を使用できるため、このコマンドはまったく必要ありません。 :)
単純なmakefileを使用すると、問題全体をより正確に解決することもできます。
CC = gcc
CFLAGS = -std=c99 -pedantic -D_XOPEN_SOURCE=600 -Wall -Werror -g
RM = rm -f
SRCS = $(wildcard *.c)
PROGS = $(patsubst %.c,%,$(SRCS))
.PHONY: all clean
all: $(PROGS)
%: %.c
$(CC) $(CFLAGS) -g3 -o3 -o $@ $<
clean:
$(RM) $(PROGS)
「Makefile」として保存して実行しますmake
。 (clean)を実行してコンパイルされたプログラムを削除しますmake clean
。 (部分的に派生男の名前)