GNU sed ワンライナーによる、ファイルインクルード処理
GNU sed の 1 行プログラムで、テキストファイルに、別のテキストファイルを、挿入する方法を説明します。 また、アイキャッチ画像を作成するための、Python スクリプトも公開します。
(There is the English(英語) page.)
(最終更新日: 2021年2月21日)
前書き
C言語の #include
ディレクティブのように、テキストファイルに、別のテキストファイルを挿入する方法を、Webで調べました。 その作業の過程で、GNU sed のマニュアルも読みました。 すると、GNU sed の ワンライナー ( 1 行のプログラム) で、それを簡単に、実現できることが分かりましたので、以下 に説明します。
また、このページの先頭に配置したアイキャッチ画像は、Python スクリプトで作成しています。そのスクリプトを、このページの 後半 で公開します。
GNU sed による、ファイルインクルード処理
動作確認に使用した OS と sed は、Ubuntu 18.04 と、GNU sed 4.4 です。
これから、3つの例を紹介します。
例1
はじめに、簡単な例を、以下に示します。
$ cat main.txt
main 1
main 2
include 'sub.txt'
main 3
$ cat sub.txt
sub 1
sub 2
$ sed -e 's/^include/cat/e' main.txt
main 1
main 2
sub 1
sub 2
main 3
ここで使用した sed の機能は、s
コマンド (substitute、置換) の e
フラグ (execute、実行) です。 この機能は、置換後の文字列を、シェルのコマンドとして、実行します。 これは、GNU sed の拡張機能です。 POSIX sed に、この機能は、ありません。
この例では、行頭の “include
” 文字列を、“cat
” に置換した後に、シェルのコマンド “cat file-name
” の実行結果を、テキストファイルに取り込んでいます。
例2
次に、Markdown ファイルに、2つの Python スクリプトファイルを、挿入する例を示します。
$ cat hello.py
print('Hello, world!')
$ cat number.py
for i in range(5):
print(i)
$ cat python.md
This is a Python script.
```python
include 'hello.py'
```
This is another Python script.
```python
include 'number.py'
```
$ sed -e 's/^include/cat/e' python.md
This is a Python script.
```python
print('Hello, world!')
```
This is another Python script.
```python
for i in range(5):
print(i)
```
例3
前述した 2つの例では、テキストファイル内で指定された、ファイルの内容全体を取り込んでいます。
最後の例では、少し形を変えて、指定されたファイルの一部だけを、取り込んでいます。
$ cat letter.txt
aaa
bbb
$ cat number.txt
111
222
333
444
555
666
$ cat inclusion.txt
sed cat 'letter.txt'
----
sed head -2 'number.txt'
----
sed sed -n '3,4p' 'number.txt'
----
sed tail -n 2 'number.txt'
$ sed -e 's/^sed//e' inclusion.txt
aaa
bbb
----
111
222
----
333
444
----
555
666
この例では、行頭の “sed
” 文字列を削除した後に、残りの文字列を、シェルのコマンドとして実行して、その結果を取り込んでいます。 この方法であれば、自由にシェルコマンドを記述できるので、柔軟なファイルの取り込みの指定が可能です。
これまでの例で示した、行頭の “include
” と “sed
” 文字列は、検索のための、単なる目印です。 これらは、自由な文字列に置き換えることができます。 例えば、“include
” を “#include
” に置き換えたり、“sed
” を、“#execute
” や “#run
” に置き換えることができます。
アイキャッチ画像を作成するための Python スクリプト
このページの先頭に配置したアイキャッチ画像 (featured image) は、以下に示す、Python スクリプトを元に作成しています。
#!/usr/bin/env python3
# Python script to make the featured-image (SVG format).
# This script is tested with Python 3.6.9 and svgwrite 1.4 on Ubuntu 18.04.
# Public Sans 1.008 is licensed under the SIL Open Font License 1.1
# https://public-sans.digital.gov/
import random
import colorsys
import svgwrite
random.seed(0)
# Attribute values of image
image_size = (image_width, image_height) = (960, 600) # 16:10
# Drawing object of svgwrite
dwg = svgwrite.Drawing(filename='feature-using-font.svg', \
size=image_size, profile='full')
# Background rectangle of image
dwg.add(dwg.rect(insert=(0, 0), size=image_size, \
fill=svgwrite.rgb(246, 246, 246)))
# Lines
for i in range(106):
line_x = random.randint(0, image_width)
line_y = random.randint((- round(image_height / 3)), image_height)
line_length = random.randint( round(image_height /15) , image_height)
line_width = round(random.uniform(0.1, 10), 4)
saturation = random.uniform(0.1, 0.9)
line_rgb = [j*100 for j in colorsys.hls_to_rgb(0.5, 0.5, saturation)]
dwg.add(dwg.line(start=(line_x, line_y), \
end=(line_x, (line_y + line_length)), stroke_width=line_width, \
stroke=svgwrite.rgb(*line_rgb, mode='%')))
# Background rectangle of text
dwg.add(dwg.rect(insert=(220, 180), size=(520, 240), fill='white'))
# Frame rectangle of text
dwg.add(dwg.rect(insert=(224, 184), size=(512, 232), fill='none', \
stroke='black', stroke_width=2))
# Text 'File inclusion'
dwg.add(dwg.text('File inclusion', fill='black', \
text_anchor='middle', insert=((image_width /2), 290), \
font_family='Public Sans', font_weight='bold', font_size=76))
# Text 'by GNU sed'
dwg.add(dwg.text('by GNU sed', fill='black', \
text_anchor='end', insert=(717, 380), \
font_family='Public Sans', font_weight='bold', font_size=48))
# Save to the SVG file
dwg.save()
このスクリプトでは、以下の、外部 Python パッケージを使用しています。
アイキャッチ画像の中の幾何学模様は、線 (SVG line) だけで構成されています。 これらの線は、スクリプトで、ランダムに生成しています。 縦線を使うことは、事前に決めています。しかし、それ以外の線の属性、つまり、線の位置、長さ、幅、色は、全て Python の乱数を基にして決めています。
この Python スクリプトを実行すると、以下に示す、SVG ファイルが作成されます。
この SVG ファイルでは、Public Sans フォントを使用しています。このフォントがインストールされていない環境で、この SVG ファイルを表示すると、上記の Python スクリプトで意図したように、フォントが表示されません。
そこで、Inkscape を使って、フォントをアウトライン化した SVG ファイルを、以下に示します。このファイルであれば、Public Sans フォントがインストールされていない環境でも、フォント部分が意図した通りに表示されます。
また、同様に、Inkscape を使って、PNG 形式に変換したファイルが、このページの先頭に配置した画像です。
コメント
コメントを投稿