web-dev-qa-db-ja.com

sedコマンドを使用して、特定の行が存在するかどうかを確認し、存在しない場合は追加します

ファイル/etc/securettyに端末を追加したい。より具体的には、pts/nを追加したいと思います。nが存在しない場合は、0-9の範囲にあります。これはsedコマンドで可能ですか?以下は、私の/etc/securettyの内容です。

# Local X displays (allows empty passwords with pam_unix's nullok_secure)
pts/0
pts/1
pts/2
pts/3

私は次のようなことを試しました:

Sudo sed '+pts/3+a pts/4' /etc/securetty

次のエラーが発生します。

sed: -e expression #1, char 3: extra characters after command
2
skrowten_hermit

対応する行に出会ったら、ポイント/数を書き留めます。 -pオプションはautoprint行になります。 eofに到達したら、ハッシュ%hを引き出し、それをgrepフィルターに渡して、印刷されなかった端末を判別し、mapを使用します。そのためのフォーマットを準備します。

Perl -lpe 'm|^pts/([0-9])$| and $h{$1}++;
   END{ print for map { "pts/$_" } grep { !$h{$_} } 0 .. 9; }
' /etc/securetty

hold spaceを番号01 2 ... 9で初期化します。pts/[0-9]行に出会うたびに、これをホールドスペースからクリップします。 eofで、ホールドスペースを取得します。数値が見つかった場合は、適切な形式にマッサージされて出力されます。

sed -e '
   # initialize the hold space with 0 1 ... 9
   1{x;s|.*|'"$(echo {0..9})"'|;x}

   # whatever be the line, it needs to be printed
   p

   # we meet a valid pts/ line
   \|^pts/[0-9]$|{
      # the hold space gets appended to the pattern space
      G
      # grab what is the pts number and search for it in the hold and
      # delete itand store back the changes into hold space.
      s|^pts/\([0-9]\)\n\(.*\)\1 |\2|;h
   }

   # weve not arrived at the eof and weve processed the input so go no further
   $!d

   # we are at the eof, so we bring back the hold space. just in case all
   # numbers were dealt with up, we simply bail out. Else, prepend the str 
   # pts/ to the numbers present and simply were home
   g;/[0-9]/!d;s/ //g
   s|[0-9]|pts/&\n|g;s/.$//

   # *TIP*: Sprinkle the l, list pattern space at various places to see 
   # whats going on.

' /etc/securetty 
3
user218374

行が欠落しているときに1行追加するには、出現箇所を1つずつ削除し、最後に追加します。

sed -n '/pattern/!p;$a pattern'

しかし、それを10パターン繰り返すのは厄介です。

sed '/pts\/[0-9]/d;$a pts/0 ...

最後の行を削除すると失敗します。したがって、逆に、最初の行が#で始まる唯一の行であると想定します。

sed '/#/a pts/0\
pts/1\
pts/2\
pts/3\
pts/4\
pts/5\
pts/6\
pts/7\
pts/8\
pts\9
/pts\/[0-9]/d'

不快な。この場合、別のツールを使用することをお勧めします。

1
Philippos

次のように、securettyファイルを検索して、欠落しているエントリーを追加できます。

for x in 0 1 2 3 4 5 6 7 8 9
do 
   grep "pts/${x}" /etc/securetty || echo "pts/${x}" >> /etc/securetty
done
sort /etc/securetty -o /etc/securetty
1
L.Ray

sedは、ファイルを1行ずつ処理します。行全体の情報を「記憶」させることは非常に困難です。

grepを使用して、ファイルに特定のパターンが含まれているかどうかを確認できます。 -f、複数のパターンを同時に指定できます。以下は完全なリストを生成しますpts/0 .. pts/9次に、指定されたファイルにすでに存在するパターンを削除し、残りのパターンをファイルに追加します。

#!/bin/bash
printf 'pts/%d\n' {0..9} \
| grep -vFf "$1"  - >> "$1".new
mv "$1".new "$1"
0
choroba