別のフォルダ(ファイル拡張子.mvw)に配置されているファイルがあります。各フォルダに移動し、文字列(ファイル* .mvw内)「D3PLOT_1DForce」をフォルダの名前に置き換えるスクリプトを作成したいと思います。
フォルダ構造は以下の通りです-
私は次のスクリプトを書きました-
#!/bin/sh
for ii in XYZ_DV_L02* ; do
(cd "$ii")
find . -iname "*.mvw" -type f -exec sed -i "s/D3PLOT_1DForce_EffPlStrainMax_VonMisesMax/"${ii}"/g" "{}" \;
done
これは機能し、文字列をフォルダの名前に置き換えますが、すべてのファイルの最初のフォルダの名前を置き換えています。 sedはforループに入っていないと思います。
Sedをループ内で機能させて、それぞれのフォルダー名を使用してファイル内の文字列を置き換えるにはどうすればよいですか?
cd
コマンドはサブシェルで実行されるため、事実上何もしません。したがって、find
コマンドは、親ディレクトリから、XYZ_DV_L02*
のサブディレクトリ名ごとに1回実行されます。 sed
を最初に呼び出すと、すべてのファイルの文字列が変更されます。次のsed
を呼び出すと、文字列は見つかりませんが、とにかく実行されます。
これを試して:
#!/bin/sh
for ii in XYZ_DV_L02* ; do
find "$ii" -iname "*.mvw" -type f -exec sed -i "
s/D3PLOT_1DForce_EffPlStrainMax_VonMisesMax/${ii}/g" "{}" +
done
StéphaneChazelasからの編集に感謝します
パスを修正するだけの質問からfind
コマンドをコピーしましたが、変更点を説明する価値があります。
${ii}
は引用符で囲まれていませんでしたが、現在はsed
引数全体を含む引用符の一部になっています。+
の代わりに\;
を使用すると、find
は、ファイルごとに1つではなく、複数のファイルに対して1つのsed
コマンドを実行します。編集
コメントからのリクエストに対して、これにより、セット[-_a-zA-Z0-9]
の後に.h3d
が続くすべてのシーケンスが、.mvw
拡張子を含むファイル名である置換テキストに置き換えられます。これが私が理解している方法です。コメントですが、役に立たないようです。パターン内のテキストにアクセスする場合は、\1
を使用できます。特定のニーズに合わせてセットを調整する必要がある場合があります。
#!/bin/sh
for ii in XYZ_DV_L02* ; do
find "$ii" -iname "*.mvw" -type f -exec sed -i -r "
s/([-_a-zA-Z0-9]+)\.h3d/${ii}.h3d/g" "{}" +
done
これを試して、
#!/bin/sh
for ii in XYZ_DV_L02* ; do
cd "$ii"
find . -iname "*.mvw" -type f -exec sed -i "s/D3PLOT_1DForce/"${ii}"/g" "{}" \;
cd ..
done
ディレクトリをforループの最初の入力フォルダに変更してファイルを見つけるのは問題ありません。ただし、次のループを実行する前に、親ディレクトリに戻る必要があります。
いくつかのサブディレクトリのみを含むディレクトリ構造があり、それぞれに変更する.mvw
ファイルがある場合は、find
を使用する必要はありません。これは、ファイルはです。
for pathname in XYZ_DV_L02*/*.mvw; do
sed -i "s/D3PLOT_1DForce/${pathname%%/*}/g" "$pathname"
done
これにより、指定されたサブディレクトリ内のすべての.mvw
ファイルが繰り返され、文字列がディレクトリ名に置き換えられます。パラメータ展開${pathname%%/*}
は、/
の文字列の最初の$pathname
以降のすべてを削除します。
テスト:
$ tree
.
|-- XYZ_DV_L02_P01
| `-- somefile.mvw
|-- XYZ_DV_L02_P02
| `-- somefile.mvw
`-- XYZ_DV_L02_P03
`-- somefile.mvw
3 directories, 3 files
$ cat XYZ_DV_L02_P0*/*.mvw
Hello D3PLOT_1DForce_EffPlStrainMax_VonMisesMax!
Hello D3PLOT_1DForce_EffPlStrainMax_VonMisesMax!
Hello D3PLOT_1DForce_EffPlStrainMax_VonMisesMax!
(ここでループを実行しています)
$ cat XYZ_DV_L02_P0*/*.mvw
Hello XYZ_DV_L02_P01_EffPlStrainMax_VonMisesMax!
Hello XYZ_DV_L02_P02_EffPlStrainMax_VonMisesMax!
Hello XYZ_DV_L02_P03_EffPlStrainMax_VonMisesMax!
明らかに、階層が深い場合は、とにかくfind
を使用する必要がありますが、find
の外部ではなく、find
の内部からループを実行できます。
find XYZ_DV_L02*/ -type f -name '*.mvw' -exec sh -c '
for pathname do
sed -i "s/D3PLOT_1DForce/${pathname%%/*}/g" "$pathname"
done' sh {} +
ここでは、パターン.mvw
に一致するディレクトリの下にあるすべてのXYZ_DV_L02*/
ファイルが見つかります。これらの見つかったファイルに対して、この回答の最初のループと同じことを行うループを実行します。これにより、任意のディレクトリの下にあるすべてのD3PLOT_1DForce
ファイルの文字列.mvw
が、対応するXYZ_DV_L02*
ディレクトリ名に置き換えられます。
関連:
この回答は、GNU sed
またはオプション引数なしで-i
を使用してインプレース編集を行うその他のsed
実装を前提としています。