たとえば、行 n+2 (バージョン行に com.icc.id.version が含まれている) の場合、com.icc.id を "abc" に置き換えます。それ以外の場合は交換しないでください。これは、「共通」フォルダのすべてのサブディレクトリにあるすべてのpomファイルに対して機能します。
<groupId>com.icc.id</groupId>
<artifactId>abc</artifactId>
<version>${project.version}</version>
<groupId>com.icc.id</groupId>
<artifactId>ifd</artifactId>
<version>${com.icc.id.version}</version>
答え1
これは必要以上のものですが、後で記録としてより多くのタスクを実行するのに役立ちます。
$ cat tst.awk
BEGIN { numLines = 3 }
{
lineNr = (NR - 1) % numLines + 1
rec[lineNr] = $0
}
lineNr == numLines {
if ( rec[3] ~ /com\.icc\.id\.version/ ) {
sub(/com\.icc\.id/,"abc",rec[1])
}
for (lineNr=1; lineNr<=numLines; lineNr++) {
print rec[lineNr]
}
delete rec
}
$ awk -f tst.awk file
(groupId)com.icc.id(/groupId)
(artifactId)abc(/artifactId)
(version)${project.version}(/version)
(groupId)abc(/groupId)
(artifactId)ifd(/artifactId)
(version)${com.icc.id.version}(/version)
すべてのサブディレクトリのすべての「.pom」ファイルに対してこれを行うには、「pomファイル」にこのような拡張子があり、次にGNU awkを使用するとします-i inplace
。
find . -name '*.pom' -exec awk -i inplace -f tst.awk {} +
答え2
n番目の行が一致すると、n番目の行とn + 1番目の行が予約状態で保存されます。 n+2番目の項目を読み、指定された内容があることを確認します。ゲーム終了後、リコールは保留され、abcに置き換えられます。
$ sed -ne '
/>com\.icc\.id</!bp
N;h;n
/\<com\.icc\.id\.version\>/{
x;s/>com\.icc\.id<\(.*\n\)/>abc<\1/;x
}
x;G;:p;p
' inp.pom
答え3
ファイルがメモリに入るのに十分小さい場合は、次のことができます。
$ awk '{lines[NR]=$0}END{for(i in lines){ if(lines[i] ~ /com\.icc\.id/ && lines[i+2] ~ /com\.icc\.id\.version/){gsub("com\\.icc\\.id","abc",lines[i])} print lines[i]}}' file
(groupId)com.icc.id(/groupId)
(artifactId)abc(/artifactId)
(version)${project.version}(/version)
(groupId)abc(/groupId)
(artifactId)ifd(/artifactId)
(version)${com.icc.id.version}(/version)
またはもう少し読みやすい:
$ awk '{
lines[NR]=$0
}
END{
for(i in lines){
if(lines[i] ~ /com\.icc\.id/ &&
lines[i+2] ~ /com\.icc\.id\.version/){
gsub(/com\.icc\.id/,"abc",lines[i])
}
print lines[i]
}
}' file
(groupId)com.icc.id(/groupId)
(artifactId)abc(/artifactId)
(version)${project.version}(/version)
(groupId)abc(/groupId)
(artifactId)ifd(/artifactId)
(version)${com.icc.id.version}(/version)
ディレクトリとサブディレクトリにある拡張子を持つすべてのファイルに適用するには.pom
(「pomファイル」が意味すると仮定します)common
、bash
gawk
shopt -s globstar
tmpFile=$(mktemp)
for file in common/**/*.pom; do
awk '{
lines[NR]=$0
}
END{
for(i in lines){
if(lines[i] ~ /com\.icc\.id/ &&
lines[i+2] ~ /com\.icc\.id\.version/){
gsub(/com\.icc\.id/,"abc",lines[i])
}
print lines[i]
}
}' "$file" > "$tmpFile" && mv "$tmpFile" "$file"
done
答え4
元の例を使用し(タグが閉じられていないxml
ため、最初に変更する必要があります)、次を使用します。dependencies
xmlstarlet
xmlstarlet ed -N "x=http://maven.apache.org/POM/4.0.0" -u "//x:dependency[x:version[contains(text(), 'com.icc.version')]]/x:groupId" -v "BANANA" data.xml
編集する
groupId
version
含まれている場所com.icc.version
とgroupId
含まれていない場所のみを変更する必要がある二重制約を考慮して、com.icc.id
以下はそのノードのみを選択して置き換える必要があります。
xmlstarlet ed -N "x=http://maven.apache.org/POM/4.0.0" -u "//x:dependency[x:version[contains(text(), 'com.icc.version')]]/x:groupId[not(contains(text(), 'com.icc.id'))]" -v 'BANANA' data.xml
またはノードのフルgroupID
テキストcom.icc.id
xmlstarlet ed -N "x=http://maven.apache.org/POM/4.0.0" -u "//x:dependency[x:version[contains(text(), 'com.icc.version')]]/x:groupId[text() !='com.icc.id']" -v 'BANANA' data.xml
@terdonのループはファイルをglobstar
見つけて出力をstdout
調べることができます。ファイルを永久に変更するには、.pom
コマンドにこのオプションを含めます。-L
xmlstarlet ed -L -N etc.....
入力する
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.icc.id</groupId>
<artifactId>solution-commons</artifactId>
<version>${com.icc.id.version}</version>
</dependency>
<dependency>
<groupId>com.icc.banana</groupId>
<artifactId>application-common</artifactId>
<version>${com.icc.version}</version>
</dependency>
<dependency>
<groupId>com.icc.id</groupId>
<artifactId>application-common</artifactId>
<version>${com.icc.banana}</version>
</dependency>
</dependencies>
</project>
出力
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.icc.id</groupId>
<artifactId>solution-commons</artifactId>
<version>${com.icc.id.version}</version>
</dependency>
<dependency>
<groupId>BANANA</groupId>
<artifactId>application-common</artifactId>
<version>${com.icc.version}</version>
</dependency>
<dependency>
<groupId>com.icc.id</groupId>
<artifactId>application-common</artifactId>
<version>${com.icc.banana}</version>
</dependency>
</dependencies>
</project>
一つ警告するこの点について。xmlstarlet
理解によって異なりますnamespace
ので、namespace
すべてのファイルで同じであれば問題ありません。異なる場合は、各ファイルを尋ねて決定し、namespace
変数に渡す必要があります。
ns=$(grep -Po "(?<=xmlns=\")[^\"]*" data.xml)