/etc/fstab
column -te
私はパイプを通して素晴らしいフォーマットのテーブルを得るのがどれほど良いかと思いました。
しかし、column
もちろん、コメント行とマウントポイント定義は認識されないため、コメントもすべてのスペースで分割され、テーブル列形式で指定されます。
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 / btrfs defaults,subvol=@rootfs,metadata_ratio=6 0 1
# /home was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 /home btrfs defaults,subvol=@home 0 2
column
で始まらないフォーマット行だけを作成する方法はありますか#
?
fstab
編集:上記の例が実際にBtrfsに有効であることを明確にする必要があるようです。サブボリュームsubvol
とインストールオプションを使用して別々にインストールできますsubvolid
。
これはまた、最初の列のデバイスがfstab
必ずしも一意である必要はないことを意味します。
答え1
私の考えに実用的な解決策は、ファイル全体がcolumn
機能するようにし、コメント行の複数のスペースを単純に縮小することです。
column -t /etc/fstab | sed '/^#/ s/ \{1,\}/ /g'
それ以外の場合は、行に番号を付け、コメント行とコメント以外の行を別々に処理し、それらをすべて貼り付ける以外にこれを行う方法はありません。
sort -nk1,1 \
<(nl -nln /etc/fstab | grep -vE '^[[:digit:]]+[[:space:]]+#'| column -t | sed 's/ \{1,\}/\t/') \
<(nl -nln /etc/fstab | grep -E '^[[:digit:]]+[[:space:]]+#') \
| cut -f2-
答え2
そして:sed
nl
nl -ba -nrz -s: /etc/fstab | \
sed '/^[[:digit:]]*:[[:blank:]]*\(#\|$\)/d;//!{s/\\/&&/g}' | \
column -t | sed 's|^0*\([[:digit:]]*\):\(.\)|\1c\\\
\2|' | sed -f - /etc/fstab
または:sed
grep
grep -nvE '^[[:blank:]]*(#|$)' /etc/fstab | \
sed -E 's/\\/&&/g;s/^([[:digit:]])*:(.*)/\1c\\\
\2/' | column -t | sed -f - /etc/fstab
または、より短く、sed
次の使用awk
:
awk '!/^[[:blank:]]*(#|$)/{print NR"c\\";gsub(/\\/,"&&");print}' \
/etc/fstab | column -t | sed -f - /etc/fstab
テストファイルの使用:
# /etc/fstab: static file system information
# <file system> <dir> <type> <options> <dump> <pass>
LABEL=ROOT / ext4 noatime,discard 0 1
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 / btrfs defaults,subvol=@rootfs,metadata_ratio=6 0 1
# /home was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 /home btrfs defaults,subvol=@home 0 2
LABEL=SWAP none swap sw,discard 0 0
UUID=7fa3-cb08 /media ext4 defaults 0 0
出力は次のとおりです
# /etc/fstab: static file system information
# <file system> <dir> <type> <options> <dump> <pass>
LABEL=ROOT / ext4 noatime,discard 0 1
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 / btrfs defaults,subvol=@rootfs,metadata_ratio=6 0 1
# /home was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 /home btrfs defaults,subvol=@home 0 2
LABEL=SWAP none swap sw,discard 0 0
UUID=7fa3-cb08 /media ext4 defaults 0 0
仕組み:
最後のコマンドは、前のコマンドで生成されたスクリプトファイルを使用し(読み取り)、マウントポイント定義のみを変更しますsed -f - /etc/fstab
(/etc/fstab
空行を含む他の行は変更しません)。f
-
stdin
4c\
LABEL=ROOT / ext4 noatime,discard 0 1
5c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 / btrfs defaults,subvol=@rootfs,metadata_ratio=6 0 1
7c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 /home btrfs defaults,subvol=@home 0 2
8c\
LABEL=SWAP none swap sw,discard 0 0
9c\
UUID=7fa3-cb08 /media ext4 defaults 0 0
最初は、nl -ba -nrz -s:
すべての行に番号を付けるために使用されます。
sed '/^[[:digit:]]*:[[:blank:]]*\(#\|$\)/d;//!{s/\\/&&/g}'
column -t
最初にコメントアウトされた行または空の行を削除し、残りの行からバックスラッシュをすべてエスケープしてから(この特別な場合は不要であることがわかっている)、マウントポイント定義のみを一覧表示するように出力をパイプします。
000004:LABEL=ROOT / ext4 noatime,discard 0 1
000005:UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 / btrfs defaults,subvol=@rootfs,metadata_ratio=6 0 1
000007:UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 /home btrfs defaults,subvol=@home 0 2
000008:LABEL=SWAP none swap sw,discard 0 0
000009:UUID=7fa3-cb08 /media ext4 defaults 0 0
これはさらに処理されます。
sed 's|^0*\([[:digit:]]*\):\(.\)|\1c\\\
\2|'
上記のスクリプトファイルを生成します。
2番目と3番目は似ています(同じ出力を生成します)。
grep -nvE '^[[:blank:]]*(#|$)' | sed -E 's/\\/&&/g;s/^([[:digit:]])*:(.*)/\1c\\\
\2/'
または
awk '!/^[[:blank:]]*(#|$)/{print NR"c\\";gsub(/\\/,"&&");print}'
マウントポイント定義のみを一致させ、バックスラッシュ(存在する場合)をエスケープし、行番号とc\
実際の行の内容を印刷します(別々の行に)。
4c\
LABEL=ROOT / ext4 noatime,discard 0 1
5c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 / btrfs defaults,subvol=@rootfs,metadata_ratio=6 0 1
7c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 /home btrfs defaults,subvol=@home 0 2
8c\
LABEL=SWAP none swap sw,discard 0 0
9c\
UUID=7fa3-cb08 /media ext4 defaults 0 0
その後、パイプを介してcolumn -t
同じスクリプトファイルを生成します。
他の方法もed
同じですが、ファイルを一度だけ読みます。
ed -s <<IN <(nl -ba -nrz -s: /etc/fstab) | sort -t: -k1,1 | cut -d: -f2-
g/^[[:digit:]]*:[[:blank:]]*\(#\|$\)/p
g//d
,w !column -t
q
IN
番号付きの行は入力として使用されed
、最初のサブコマンドはp
最初にコメントアウトされた行または空白行(g
)の両方を印刷し、2番目のサブコマンドはd
それを削除してから残りの行を入力()としてw
shell(!
)コマンドに渡しますcolumn -t
。出力全体sort
が編集され、cut
先行番号が削除されます。
答え3
「レビューを送信する前に削除するのはどうですか?」という提案がcolumn
まったく価値がないわけではありません。
#!/bin/sh
nl -ba /etc/fstab | sed "s/^ *//; s/\t/ /" > file0
grep "^[0-9][0-9]* #" file0 > file1
grep -v "^[0-9][0-9]* #" file0 > file2
(cat file1; column -t file2) | sort -n | sed "s/^[0-9][0-9]* *//"
nl –ba
各行には番号が付けられています。%6d\t
つまり、数字の前にスペースがあり、その後にタブ文字が続きます。先行スペースを削除し、タブ文字をスペースに置き換えて出力sed "s/^ *//; s/\t/ /"
に似ています。コマンドcolumn
は、コメント化された行とコメント化されていない行にgrep
分けられます。 (方法file0
file1
file2
XX*
X
0個以上のX
s、つまり1つ以上のX
sが続きます。これは「貧しい人々のバージョン」ですX+
。つまり、1つ以上のsを移植可能/一般的な方法で表現する方法ですX
。 )各ファイルは行番号を保持します元のファイル/etc/fstab
から。
(cat file1; column -t file2)
コメント化されていない行を実行して、column –t
結果をコメント化された行(水平間隔は変更されません)にリンクします。次に、sort –n
行を元の順序に復元し、sed "s/^[0-9][0-9]* *//"
行番号を削除します。
出力:
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 / btrfs defaults,subvol=@rootfs,metadata_ratio=6 0 1
# /home was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169 /home btrfs defaults,subvol=@home 0 2
これは、空白行と空白を含むコメント行(つまり、タブまたは2つ以上の空白を含む文字列)をサポートしますが、インデントされた行(たとえば、リーダータブまたはスペース)。
このスクリプトを少し強化したい場合(つまり、本番バージョンに似ている)、次のことができます。
- 一時ファイルを
/tmp
任意にmktemp
生成された名前のファイルに置き換えます。 - 完了したら、一時ファイルを削除します。
- 適切な場合は使用するように変更してください
[0-9]+
(システムが古すぎる場合(たとえば、Solaris、AIX、またはGNUツールのないシステムなど)には適用されない可能性があります)。 file1
and を削除file2
し、最後の行を次のように圧縮します。(grep "^[0-9][0-9]* #" file0; grep -v "^[0-9][0-9]* #" file0 | column -t) | …
しかし、いくつかの行を書いて、より明確に書くのが良いようです。
- インデントされた行のサポートを追加します。
答え4
列だけではこれを行うことはできないようです。これを行うための簡単なスクリプトを書くことはそれほど難しくありません。
編集:これはうまくいくかもしれませんし、少し短いかもしれません。列を通過しましたが、上記の元の例で試しました。私はこれが空の行を削除することがわかったので、それが問題であれば、まだ少しトリミングする必要があるかもしれません。
#!/bin/bash
INPUTFILE="${1}"
IFS=$'\r\n' GLOBIGNORE='*';
COMMENTS=(`grep -n ^# "${INPUTFILE}"`)
ENTRIES=(`grep -n -v ^# "${INPUTFILE}" | column -t`)
TMPTAB=(`printf "%s\n" ${ENTRIES[@]} && printf "%s\n" ${COMMENTS[@]}`)
NEWTAB=(`printf "%s\n" ${TMPTAB[@]} | sort -n -t: -k1 | sed 's/^[0-9]\+://'`)
printf "%s\n" ${NEWTAB[@]}
ここに元の答えを残しますが、@scottが指摘したように、いくつかの有効なfstabでは機能しません。
#!/bin/bash
# columnize the non-comment lines
TABS=`grep -v ^# /etc/fstab | column -te`
# read the original fstab
while read LINE
do
echo "${LINE}" | grep ^# > /dev/null
# if it is a comment line just write it in
if [ $? -eq 0 ]
then
echo "${LINE}" >> new.fstab
else
# otherwise get the matching entry from the columnized fstab
ENTRY=`echo "${LINE}" | awk '{ print $1 }'`
echo "${TABS}" | grep ^"${ENTRY}" >> new.fstab
fi
done < /etc/fstab