異なるファイル名を除いて、同じディレクトリに同じ.conf
ファイルがいくつかあります。一意の名前を持つ.conf
ファイルごとに、ファイル内の文字セットをファイル名に置き換えたいと思います。例えば:
現在、すべてのファイルで:
datafname = example.nex
ofprefix = best.example
理想的な出力:
ファイル名:25.conf
datafname = 25.nex
ofprefix = best.25
ファイル名:26.conf
datafname = 26.nex
ofprefix = best.26
sed
を使用してこれらすべてのファイルを検索し、次のような方法でテキスト文字列を検索してファイル名に置き換えることができると考えました。
sed -i conf 's/example/echo $f/g' *
しかし、これは適切に機能していません。誰もこれを行う方法についての提案を持っているでしょうか?
できるよ:
for f in *.conf; do
base=$(basename "$f" '.conf') # gives '25' from '25.conf'
sed -i.before "s/example/$base/g" "$f"
done
-i
スイッチをsed
に使用する場合、-i
がファイルを変更するため、sed
コマンドが機能することを完全に確認する必要がありますin-place。これは、生成された出力が入力ファイルを上書きすることを意味します。置換コマンド(s/…/…/
)が間違っていると、空のファイルが作成され、バックアップが作成されない場合があります。そのため、-i.before
を使用しました。これにより、元のコンテンツを含む*.before
ファイルが残ります。
Forループを使用して、ファイルを反復処理できます。パラメーター拡張を使用して、ファイル拡張子を削除します。式を二重引用符で囲みます。そうしないと、変数は展開されません。
#! /bin/bash
for f in *.conf ; do
b=${f%.conf}
sed -i "s/example/$b/" "$f"
done
GNU parallel
を使用して、ループなしでタスクを実行できます。 :
parallel sed -i.old s/example/{.}/ {} ::: *.conf
これは、parallel
がCPUコアごとに1つのジョブを実行するため、編集するファイルのlotがある場合に特に役立ちます。
-i.old
は、ファイルi
n-placeを編集し、元のファイル名に.old
拡張子を追加してバックアップを作成します(バックアップが不要な場合は.old
を削除しますが、覚えていない場合は ' tバックアップがあります)s/example/{.}/g
は、s
ubstitute example
を意味し、拡張子のない入力ファイル名({.}
)で、g
lobally(=すべての出現に対して){}
は入力ファイル名に置き換えられます:::
は、実行するコマンドとそれに渡す引数を分離します*.conf
は、現在のディレクトリ内のすべての.conf
ファイルと一致しますFILENAME
変数がファイル名に自動的に設定されているawkを使用します(GNU awkの場合、インプレース編集も行います)。
$ for i in {20..26}; do printf "%s\n" "datafname = example.nex" "ofprefix = best.example" > $i.conf; done
$ gawk -i inplace 'FNR == 1 {split(FILENAME, file, ".")} {gsub("example", file[1])} 1' *.conf
$ cat 25.conf
datafname = 25.nex
ofprefix = best.25
FNR == 1 {split(FILENAME, file, ".")}
:各ファイルの最初の行で、.
でファイル名を分割し、file
配列に保存します{gsub("example", file[1])} 1
:すべての行について、example
をfile
配列の最初の要素に置き換えて印刷します。