web-dev-qa-db-ja.com

sedを使用して、各段落の最初の単語を<i> </ i>でカプセル化しますか?

だから明らかに私は巨大な文書の各段落の最初の単語をイタリック体にしようとしています。接頭辞を追加するのは比較的簡単だと思いますが、行末ではなく、接尾辞の最初のWordのみをどのように描くのですか?ファイルはスペースで区切る必要があります。

sed -e 's/^/<i>/' file > file.new

異なる構文でsedを2回実行する必要がありますか、それとも1つのコマンドで実行できますか?失敗した場合に備えて、新しいファイルに出力しています。

ファイルの数行の例を次に示します。

Snapdragon  Plant with a two-lipped flower.

Snap-fastener  = *press-stud.

Snapper  Any of several edible marine fish.

Snappish  1 curt; ill-tempered; sharp. 2 inclined to snap.

以下のようにしたい:

<i>Snapdragon</i>  Plant with a two-lipped flower.

<i>Snap-fastener</i>  = *press-stud.

<i>Snapper</i>  Any of several edible marine fish.

<i>Snappish</i>  1 curt; ill-tempered; sharp. 2 inclined to snap.

すべての行が単一であるわけではなく、一部の用語には複数の定義行があります。

4
DanMan3395

Sedを使用して、

  • 行の先頭に文字がある場合、
  • ホワイトスペース以外の文字をキャプチャし、
  • 取り込んだ文字を、周囲の<i> ... </i>に置き換えます。

このような:

sed '/^[a-zA-Z]/ s!\([^ ]*\)!<i>\1</i>!' < file > file.new

このサンプル入力では:

Snapdragon  Plant with a two-lipped flower.

Snap-fastener  = *press-stud.

Snapper  Any of several edible marine fish.

Snappish  1 curt; ill-tempered; sharp. 2 inclined to snap.

出力は次のとおりです。

<i>Snapdragon</i>  Plant with a two-lipped flower.

<i>Snap-fastener</i>  = *press-stud.

<i>Snapper</i>  Any of several edible marine fish.

<i>Snappish</i>  1 curt; ill-tempered; sharp. 2 inclined to snap.

Sedコマンドの断片を分解するには:

  • /^[a-zA-Z]/-これはアドレスフィルターです。これは、この正規表現に一致する行にのみ後続のコマンドを適用することを意味します。正規表現では、文字(小文字のa-zまたは大文字のA-Z)が^の行の先頭に続く必要があります。

  • s!\([^ ]*\)!<i>\1</i>!-これは検索および置換コマンドです。検索と置換の間に区切り文字を使用します。共通の区切り文字はスラッシュですが、置換テキストにはスラッシュがあるため、区切り文字を感嘆符!に変更しました。検索語には2つの部分があります。エスケープする必要のあるキャプチャ括弧と、「スペースを除いて、0回以上一致する[^ ]*」という正規表現*です。置換テキストは\1でグループをキャプチャし、HTMLタグで囲みます。

空でない各行を段落タグでさらにラップするには、別のsed式を追加します。

sed -e '/^[a-zA-Z]/ s!\([^ ]*\)!<i>\1</i>!' -e '/./ { s/^/<p>/; s!$!</p>! }' < file

追加の表現は言う:

  • (任意の)文字が1つある行に一致します-これは空白行をスキップします
  • {次の2つのコマンドをグループ化
  • ^の行の先頭を検索して、開始タグで置き換える
  • 行の終わり$を検索し、段落の終了タグで置き換えます
  • }グループ化を終了
4
Jeff Schaller

sedでこれを行うことができます:

_$ sed '/^$/n;s#^\([^ ]*\)#<i>\1</i>#' input.txt
<i>Snapdragon</i>  Plant with a two-lipped flower.

<i>Snap-fastener</i>  = *press-stud.

<i>Snapper</i>  Any of several edible marine fish.

<i>Snappish</i>  1 curt; ill-tempered; sharp. 2 inclined to snap.
_

説明

上記のsedには2つのブロックが含まれています。最初のブロックは、空白行__/^$/_を検出し、それらをスキップしますn

  • 空白行をスキップする_/^$/n_

2番目のブロックは、すべての面倒な作業_s#..#..#_を実行し、スペース\([^ ]*\)を含まないサブ文字列を検出します。このパターンは、それをラップする\(..\)を介して「保存」されるため、後で_\1_を介して再利用できます。

  • 最初のスペースまでの部分文字列に一致\([^ ]*\)
  • 一致、_\1_を保存し、_<i>...</i>_でラップします
2
slm

あなたはawkで試すことができます:

awk '{$1="<i>$1</i>"; print $0}' file > file.new

1
Siva

sed拡張正規表現

行がインデントされているかどうかに関係なく、<i>を使用して置換パターンの検索語を表し、</i>(スペース以外)文字の最初の部分文字列の周りに[^[:space:]]タグと&タグを配置します。

-Eを使用してsedの拡張正規表現を有効にするには:

sed -E 's/[^[:space:]]+/<i>&<\/i>/' file

/を使用して検索用語と置換用語を区切る場合は、他の/の前に\を付ける必要があります(ここの2番目のタグのように)。 /以外の文字を使用して検索用語と置換用語を区切ることにより、その文字が用語に表示されない限り、この余分な手順を回避できます。たとえば、コンマを使用します。

sed -E 's,[^[:space:]]+,<i>&</i>,' file

それが最短の方法です。

+(パターンの1つ以上のオカレンスを表す)は通常の(-eではなく-E)正規表現では機能しませんが、*(0回以上のオカレンスを表す)を使用して同じことを少し実行できますよりタイピング:

sed -e 's,[^[:space:]][^[:space:]]*,<i>&</i>,' file
0
Gaultheria