Linux パイプの片側から別の側に変数を直接渡すことはできません。これは、パイプの両側のコマンドがfork()
ed サブシェルで実行されるためです。つまり、これらのコマンドは、親シェル プロセスの独自のコピー (パイプの両側に 1 つ) で実行されます。したがって、親プロセスの変数のコピーを受け取りますが、親プロセスの元の変数を直接変更することはできません。したがって、パイプの両側のサブシェル内の変数のコピーは、親から同じ初期値を継承する必要があるという事実を除いて、互いに完全に独立しています。
これを説明するために、次のコマンドを実行できます。
a=100
(echo "LHS pre: $a" 1>&2; ((a++)); echo "LHS post: $a" 1>&2) | ( echo "RHS pre: $a" 1>&2 ; ((a+=10)); echo "RHS post: $a" 1>&2 )
echo "Parent final: $a" 1>&2
出力は次のとおりです。
RHS pre: 100
RHS post: 110
LHS pre: 100
LHS post: 101
Parent final: 100
ここではa
、親シェル プロセスで変数を 100 に設定します。2 番目のコマンドのパイプの LHS と RHS (左側と右側) は両方とも、この変数のコピーを受け取ります。LHS は copy 変数を出力し、それを 1 ずつ増やしてから、再度出力します。RHS は copy 変数を出力し、それを 10 ずつ増やしてから、再度出力します。次に、親シェルは元のバージョンの変数を出力します。LHS サブシェルと RHS サブシェルが変数のコピーを完全に独立してインクリメントしていることがわかります。また、親のオリジナルは、LHS および RHS サブシェルからの変更の影響をまったく受けていないこともわかります。
これで理論は終わりです。実際に直面している問題の解決策をいくつか紹介します。それほど洗練されていないかもしれませんが、sedとawkのマンページを読むことを避けるためにできる限りのことをしている私たちのために、いくつかの代替手段があります:
- 「シンプルな」ツール -
head
、tail
、grep
およびcut
- 純粋なバッシュで
.
ubuntu@ubuntu:~$ cat stats.txt
The first line
The 2nd line
the line with stats in it
another line
another line with stats
another line
the last line
ubuntu@ubuntu:~$ tail -n-$(($(grep -n stats stats.txt | head -n1 | cut -d: -f1)+1)) stats.txt
another line
another line with stats
another line
the last line
ubuntu@ubuntu:~$ fl=""; while read -r line; do [ "$fl" ] && echo -e $line; [[ $line =~ stats ]] && fl=1; done < stats.txt
another line
another line with stats
another line
the last line