sed 명령을 사용하여 특정 줄이 있는지 확인하고, 없으면 추가하세요.

sed 명령을 사용하여 특정 줄이 있는지 확인하고, 없으면 추가하세요.

파일에 더 많은 터미널을 추가하고 싶습니다 /etc/securetty. 보다 구체적으로 존재하지 않는 경우 범위 내에 있는 pts/n위치를 추가하고 싶습니다 . 명령을 통해 이것이 가능합니까 ? 내 내용은 다음과 같습니다 .n0-9sed/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

답변1

해당 줄을 만나면 pts/ 번호를 기록해 둡니다. 옵션 -pautoprint라인입니다. 도달하면 eof해시를 꺼내어 필터 %h를 통해 전달하여 grep어떤 터미널이 인쇄되지 않았는지 확인하고 map해당 형식을 준비하는 데 사용합니다.

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

숫자 0 1 2 ... 9로 초기화합니다 hold space. 선을 만날 때마다 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 

답변2

누락된 줄을 추가하려면 각 항목을 제거하고 끝에 추가하면 됩니다.

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'

끔찍한. 이 경우에는 다른 도구를 사용하는 것이 좋습니다.

답변3

모든 pts/N줄을 제거한 다음 모두 다시 추가하십시오.

{ grep -xv '^pts/[0-9]$' /etc/securetty; printf 'pts/%d\n' {0..9}; } > /etc/securetty.new
cat /etc/securetty.new
mv /etc/securetty.new /etc/securetty

또한 즐겨 사용하는 텍스트 처리 도구를 사용하여 이 작업을 한 번에 수행할 수도 있습니다.ed

ed -s /etc/securetty <<IN
g/^pts\/[0-9]$/d
.r ! printf pts/\%d\\\n {0..9}
,p
q
IN

( 내부에서 편집하려면 ,p로 대체) 또는wsed

{ printf '%s\\\n' '$a' pts/{0..8}
printf '%s\n' 'pts/9' '/^pts\/[0-9]$/d'
} | sed -f- /etc/securetty

그건 일반과 거의 똑같습니다

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' /etc/securetty

(사용sed ~와 함께-i파일을 그 자리에서 편집하려면)

답변4

sed파일을 한 줄씩 처리하므로 여러 줄에 걸쳐 정보를 "기억"하도록 만드는 것은 매우 어렵습니다.

grep파일에 특정 패턴이 포함되어 있는지 확인하는 데 사용할 수 있습니다 . 을 사용하면 -f동시에 여러 패턴을 제공할 수 있습니다. 다음은 전체 목록 pts/0.. 을 생성한 pts/9다음 지정된 파일에 이미 존재하는 패턴을 제거하고 나머지 패턴을 파일에 추가합니다.

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

관련 정보