2行目までのすべての内容を印刷したいです。スタートwith * i
(アスタリスク、スペース、小文字I)は、この行とこの行を含む、その後のすべての項目をそれぞれ除外します。
たとえば、次のテキストファイルがあるとします。
* misc: go to the park
with your dog
* important: sell badges
the bigger the pricier
24 left right now
* important: go to the mall
get clothes
* important: finish homework
まずこれを印刷したいです。
* misc: go to the park
with your dog
* important: sell badges
the bigger the pricier
24 left right now
それからこれ:
* important: go to the mall
get clothes
* important: finish homework
sedを使用してこれを行うにはどうすればよいですか?
頑張った
sed '/\* [^i]/,$ { /\* [^i]/,$ d}' /path/to/txt/
しかし、以前のすべての内容を印刷します。初めて一致する行。
各部分を抽出するには、2つの別々のスクリプトが必要です。
答え1
私が提案するawk
処理(私はこれがより柔軟で強力であると信じています):
awk '/^\* i/ && ++c == 2{ print r ORS; r=""; c=0 }
{ r=(r? r ORS:"")$0 }
END{ print r }' file
出力:
* misc: go to the park
with your dog
* important: sell badges
the bigger the pricier
24 left right now
* important: go to the mall
get clothes
* important: finish homework
現在の簡単なケース(追加ロジックなし)の場合、次のように短縮できます。
awk '/^\* i/ && ++c == 2{ print "" }1' file
必要な部分を個別に抽出するには、まだ単一のコマンドを使用しますが、条件付き値(最初の部分、前の部分)、または(2番目の部分、次の部分)を受け入れるawk
動的パラメータを使用します。part
1
2
計画:
awk -v part=[12] '/^\* i/ && ++c == 2{ if (part == 1) exit; else f=1 } part == 1 || (part == 2 && f)' FILE
使用法:
- 印刷「これから」部分:
$ awk -v part=1 '/^\* i/ && ++c==2{ if (part==1) exit; else f=1 }
> part==1 || (part==2 && f)' file
* misc: go to the park
with your dog
* important: sell badges
the bigger the pricier
24 left right now
- 印刷「後ろに」部分:
$ awk -v part=2 '/^\* i/ && ++c==2{ if (part==1) exit; else f=1 }
> part==1 || (part==2 && f)' file
* important: go to the mall
get clothes
* important: finish homework
答え2
awkよりも複雑なsedを使用することもできます。
cat sedscript.sh
deb=$1
sed 's/.*/'"$deb"'\n&/
:A
/^1/{
N
/\n\* i/!bA
:B
N
/\n\* i[^\n]*$/!bB
s/\n[^\n]*$//
s/[^\n]*\n//
q
}
:C
/^2/{
N
/\n\* i/!bC
:D
N
/\n\* i[^\n]*$/!bD
s/.*\n//
:E
N
bE
q
}
d
' $2
次のように呼び出します。
最初の部分については
./sedscript.sh 1ファイル
第二部のために
./sedscript.sh 2 入力ファイル