次のスクリプトを作成しようとしています。
- 名前に「foobar」を含むファイルを探す
- スクリプトはこのファイルで実行され、出力は自動的に生成され、検索されたファイルと同じ名前の新しいCSVファイルに保存する必要があります。唯一の違いは、拡張子がCSVに変更されることです。
これは私のスクリプトです。 :
#!/bin/bash
# search for file containing "foobar" as a name in the directory
for file in /home/user/Documents/* ;
do
if [[ "$file" == *"$foobar"* ]]; then
touch /home/user/Documents/collectCSV/csv1.csv
# executing script of modelising foobar file ==> extract some data from $foobar file and insert it in the
# created file csv1.csv
/home/user/scriptModelise.pl $file >> /home/user/Documents/collectCSV/csv1.csv
else
echo "foobar file not found"
fi
done
問題は、このファイルの生成方法が静的であることです。ファイルの自動生成に失敗しました。私は、foobarファイルを見つけたときに作成される新しいファイルでそれをモデル化することを意味します。
助けが必要ですか?
答え1
使いやすくなります(このように変数の引用を解除すると、すでにzsh
構文を使用しています)。zsh
#! /bin/zsh -
files=(/home/user/Documents/*foobar*(N))
if (($#files)) {
ret=0
for f ($files) {
/home/user/scriptModelise.pl $f > $f:h/collectCSV/$f:t:r.csv || ret=$?
}
exit $ret
} else {
echo >&2 No non-hidden foobar file
exit 1
}
csh
と同様に、head(dirname)、tail(basename)、root(拡張子の削除)$f:h
です。$f:t
$f:r
((arithmetic expression))
ksh
評価など算術表現ゼロ以外の値である場合は true を返します。$#array
、ksh
s を連想させる${#string}
配列の長さを提供します (要素数で表示)。ksh
/ では、bash
配列は実際には別々の型ではないため、${#array[@]}
インデックス0${#array}
の要素の長さ(文字)が必要です。(N)
:glob修飾子。一致するものがない場合は空の状態に展開されます。$f
、$files
:他のBourne様シェルとは異なり、変数は引用符で囲む必要はありません(NULL値を含まない限り)。他のシェル(ksh、bash、yash)では、"$f"
とが必要です"${files[@]}"
。
答え2
努力する
for file in *"$foobar"*
do
dest="$(echo $file| sed -e 's/\(.*\)\.[^\.]*$/\1.csv/' )"
if test -f "$file"
then
/home/user/scriptModelise.pl "$file" >> /home/user/Documents/collectCSV/$dest
else
echo "no $foobar file"
fi
done
どこ
\(.*\)\.[^\.]*$
ランダムな文字(パターンの終わり)と点が続き、行の終わりまでの点ではなくパターンをキャプチャします。\1.csv
見つかったパターンの挿入、.csvの追加*"$foobar"*
*foobar*
一致するファイルがない場合は、リテラル(正しい値を含む)に展開されます。したがって、必要ですtest -f "$file"
編集する:
\(.*\)\.[^\.]*$
(左:検索モード)
(_はプレースホルダーです)
__.*__________
任意の文字を含むパターン(ドットには特別な意味があります:任意の文字)__.*__\._______
任意の文字の後に点があるパターン(エスケープ点は一般点です)__.*__\.[^\.]*$
行末までの任意の文字(パターン終了)と点があり、点ではない([^\.]*
)があるパターン(ドル記号は行末に特殊)\(__\)__________
パターンの最初の部分をキャプチャします。\1.csv
(右、何をすべきか)\1____
\1
\( \)
パターン全体の最初、2番目など\2
の内容を一致させます。&
答え3
これはGNU Parallelでは簡単に行うことができ、ボーナスとして一度に複数のファイルを処理することもできます。
parallel /home/user/scriptModelise.pl {} ">>" {.}.csv ::: *"$foobar"*
一致するファイルがないとエラーが発生するため、*"$foobar"*
最初に確認するか、find
名前をパイプするか、bashオプションを設定する必要がありますfailglob
。