特定の行で、別の変数テキストの後に変数テキストを挿入しようとしています。以下は、これまでの私の試みです。私が知る限り、引用符をエスケープしてawk
変数が表示され、適用され続けるようにできれば、うまくいくはずですが、その方法がわかりません。
#!/bin/sh
VAR=$(head -n1 ~/Scripts/tmp/file.txt)
VAR1=$(head -n1 ~/Scripts/tmp/file1.txt)
awk '/$VAR/ { print; print "$VAR1"; next }1' ~/Scripts/tmp/file.txt
答え1
文字列を awk スクリプトに渡すには、環境変数を介して渡します。
export VAR VAR1
awk '
1
$0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt
ロジックをシンプルにするためにスクリプトを再編成しました。また、正規表現のマッチングを文字列の比較に置き換えました。正規表現のマッチングでは、$VAR
正規表現として扱われ、文字列の比較は実行されません。また、そのために必要となる の値 (これは Perl 構文であり、awk ではありません)/$VAR/
も使用されません。VAR
match($0, VAR)
実際には機能しない他の解決策についての注意 (変数に特殊文字が含まれていない場合にのみ機能します。どの文字が特殊であるかは方法によって異なります)。
awk -v awkvar="$VAR" '$0 == awkvar …'
行の内容内のバックスラッシュを展開します。awk "/$VAR/" …
シェルは の値をVAR
awk スニペットとして展開します。たとえば、file.txt
が含まれている場合^/ {system("touch ~/naughty")} /
、コマンドがtouch ~/naughty
実行されます。
別の方法としては、awk にすべてのファイルを読み取らせることです。
awk '
BEGIN { VAR1 = getline <"~/Scripts/tmp/file1.txt"; }
NR == 1 {VAR = $0}
1
$0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt
答え2
考えられる AWK の解決策の 1 つ:
awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'
すべての外部変数を囲む ' 引用符を分割します。
他の投稿で提案されているように、変数を渡す別の解決策としては、VAR1 を awk 変数として渡すことが考えられますが、VAR を使用するパターンでは、依然として一重引用符ブロック エスケープを実行する必要があると思います。
awk -v var=$VAR1 '/'$VAR'/ { print; print var; next }1'
代わりに sed を試すこともできます :) この種の置換用に特別に設計されています。
sed "s/$VAR.*/\0\n$VAR1/" ~/Scripts/tmp/file.txt
1 行に複数の VAR インスタンスを記述できる場合は、sed コマンド (グローバル) の最後に g を追加して、最初に見つかった一致で停止しないようにします。
sed "s/$VAR.*/\0 $VAR1/g" ~/Scripts/tmp/file.txt
重要: VAR または VAR1 変数に '/' 文字が含まれていないことを確認してください。含まれている場合は、awk または sed でエスケープする必要があります。または、sed でコマンドの区切り文字を ';' などの別の文字に変更できます。例:
sed "s;$VAR.*;\0\n$VAR1;" ~/Scripts/tmp/file.txt
sed コマンドの説明:
sed コマンドの前後に一重引用符ではなく二重引用符を使用して、VAR や VAR1 などの変数がその値に置き換えられるようにします。これは、sed によってコマンドが実行される前に行われるため、変数の内容に / が存在する可能性がある場合は、それを処理する必要があります (awk の場合も同様です)。
's' は、次の形式の置換コマンドを記述していることを示します:
s/<パターン>/<置換パターン>/
s の直後の '/' は、コマンドのセクションを区切るために使用される区切り文字です。したがって、; を配置する場合は、上記のようにすべての場所で ; を使用する必要があります。一致するパターンは、$VAR 変数の内容になります。置換パターンは \0 で、パターンに一致したもの、新しい行 '\n'、および VAR2 の内容を出力することを意味します。
OOPS は、以下の行の部分を見逃しました。固定パターンです。
答え3
を使用する場合は、オプションを使用して変数を にawk
渡す必要があります。 bash
awk
-v
awk -v v=$VAR -v v1=$VAR1 '/v/ { print; print v1; next }1' ~/Scripts/tmp/file.txt
ただし、より正確で詳細な解決策については、Rob の回答を確認してください。