
LINEnum=$(grep -nr "#32" IM_DlCtrlRef.txt | cut -d : -f 1)
for j in $LINEnum
do
echo $j
sed -n '$j,4800p' IM_DlCtrlRef.txt >> IM_DlCtrlRef_bak
for insertl in {1..4}
do
cat zero.txt >> IM_DlCtrlRef_bak
done
done
答え1
主な問題 (構文エラーの原因となるもの) は次の行にありますsed
。
sed -n '$j,4800p' IM_DlCtrlRef.txt >> IM_DlCtrlRef_bak
$j
スクリプト内のシェル変数をsed
開始行番号として使用したいのですが(スクリプトはファイルから 4800 行までを抽出します)、一重引用符を使用してシェルが変数を展開できないようにしています。これは、sed
開始アドレスとして取得されることを意味し、混乱を招きます。$j
sed
$j
その行を二重引用符に変更するだけです。
さて、完全なスクリプトを見てみましょう:
LINEnum=$(grep -nr "#32" IM_DlCtrlRef.txt | cut -d : -f 1)
for j in $LINEnum
do
echo $j
sed -n "$j,4800p" IM_DlCtrlRef.txt >> IM_DlCtrlRef_bak
for insertl in {1..4}
do
cat zero.txt >> IM_DlCtrlRef_bak
done
done
これには、修正したいかどうかわからないスタイルの問題とパフォーマンスの問題がいくつかあります。
for
まず、すべての行番号を変数に読み込みます。これはメモリの無駄ですが、 -loop がループする対象を正確に知る必要があるため、これを行う必要があります。
別の解決策としては、行番号を 1 つずつ読み取ることです。
grep -nr "#32" IM_DlCtrlRef.txt | cut -d : -f 1 |
while read j; do
# ...
done
つまり、スクリプトが取り込むことができるデータの量に制限はありません。
ちなみに、は再帰的に検索-r
するので、ここでは必要ありません。固定文字列 (正規表現ではない) を探しているので、grep
に置き換えます。-F
しかし、一致する行の行番号のみに関心がある場合は#32
、パイプ全体を次のように置き換えることができます。
sed -n '/#32/=' IM_DlCtrlRef.txt
このsed
コマンドは=
行番号を出力します。
最後の仕上げで、脚本は
sed -n '/#32/=' IM_DlCtrlRef.txt |
while read j; do
echo $j
sed -n "$j,4800p" IM_DlCtrlRef.txt >>IM_DlCtrlRef_bak
for insertl in {1..4}; do
cat zero.txt >>IM_DlCtrlRef_bak
done
done