파일의 패턴을 따르는 여러 줄을 포함하는 문자열을 반환합니다.

파일의 패턴을 따르는 여러 줄을 포함하는 문자열을 반환합니다.

여러 줄이 포함된 파일이 있습니다. 특정 패턴 뒤에 나타나는 문자열을 얻으려고 합니다...

이것은 내가 실행하려는 명령입니다.

sed -n -e 's/^.*DB_PASS=//p' <<< $(cat /root/dadosDB)

하지만 내가 원하는 행만 제공하는 대신 지정된 패턴 이후의 모든 항목을 제공합니다...

내 기대:

해당 행을 포함하는 출력만 반환 DB_PASS하고 다른 행은 무시합니다.

이 명령이 수행하는 작업은 다음과 같습니다.

전체 파일에서 이 패턴 뒤에 나타나는 모든 것을 인쇄하고 DB_PASS그 앞에 나타나는 모든 것을 무시합니다.

도움을 주시면 감사하겠습니다!

이것이 내가 가지고 있는 것입니다 dadosDB:

DB_USER=myusername
DB_PASS=mypassword
DB_NAME=mydatabase

DB_PASS=나는 다음 내용을 무시하고 다음 내용을 가져오고 해당 줄에서 멈추고 싶습니다 .

실제 출력 sed:

$ sed -n 's/^.*DB_PASS=//p' <<< $(cat /root/dadosDB)
mypassword DB_NAME=mydatabase

나는 필요하다:

mypassword

답변1

이 결과를 얻는 이유는 명령을 sed파일에 직접 적용하는 것이 아니라 명령 대체 결과에 적용하기 때문입니다.

이는 텍스트 처리가 실제로 적용되지 않음을 의미합니다.

DB_USER=myusername
DB_PASS=mypassword
DB_NAME=mydatabase

cat오히려 이는 압축된 행을 인용되지 않은 명령으로 대체한 후 파일 내용에 적용된 명령의 결과입니다.

당신이 시도한다면

echo $(cat /root/dadosDB)

출력이 다음과 같은 것을 알 수 있습니다.

DB_USER=myusername DB_PASS=mypassword DB_NAME=mydatabase

모두 별도의 줄이 아닌 한 줄에 있습니다. 다음과 같이 큰따옴표로 명령 대체를 넣으면

echo "$(cat /root/datosDB)"

개행 문자는 유지됩니다.

핵심은

  1. cat명령 대체를 원하지도 요구하지도 않습니다 .
  2. 큰따옴표를 넣지 않고 명령 대체를 사용하면 개행 문자가 손실됩니다(참조:이 질문과 답변의 예). (1)

간단히 말해서:

사용

sed -n -e 's/^.*DB_PASS=//p' /root/dadosDB

더 구체적으로)

sed -n -e 's/^DB_PASS=//p' /root/dadosDB

시작 키워드가 다른 행을 제외하지만존재하다 DB_PASS.

참고: 당신이 쓴"그리고 그 줄에서 멈추고 아래 줄은 무시하세요."인쇄하고 싶다는 뜻인 것 같아요나중에DB_PASS하지만 다음 줄은 해당되지 않습니다(기술적으로는 뒤에도 나타납니다) DB_PASS. 이 줄로 시작하는 줄이 더 있을 수 있고 DB_PASS첫 번째 줄만 일치하는지 확인하려면 약간 조정해야 합니다.

sed -n -e '0,/DB_PASS/s/^DB_PASS=//p' /root/dadosDB

(1) 특정 경우의 문제는 쉘(Bash라고 가정)이 인용되지 않은 대체 항목을 사용하여 "Here-strings"를 처리하는 방식이므로 (@steeldriver가 지적했듯이) 더 좋습니다. 데모는

cat <<< "$(cat /root/dadosDB)"

그리고

cat <<< $(cat /root/dadosDB)

이 행동에는Bash v4.4에서 변경되었습니다.: 이전에는 이 두 명령의 출력이 위에서 언급한 예와 동일했습니다 echo. Bash의 이후 버전에서는 따옴표가 없는 명령 대체로 인해 더 이상 토큰화 및 여러 줄 출력의 후속 압축이 발생하지 않습니다.


더 자세히 알고 싶으시면 확인해 보시는 것도 좋을 것 같습니다

또한 다음을 사용하여 스크립트를 확인하는 것이 좋습니다.shellcheck는 구문(및 기타) 오류를 방지하기 위해 많은 Linux 배포판에서 독립 실행형 도구로도 사용할 수 있습니다.

답변2

awk(나에게) 이 작업보다 더 나은 옵션 처럼 보이는 다음을 사용할 수도 있습니다 .sed

$ awk -F'=' '$1 == "DB_PASS" { print $2 }' /root/dadosDB
mypassword

grep또 다른 옵션은 다음을 조합하는 것입니다 cut.

$ grep "^DB_PASS=" /root/dadosDB | cut -d= -f2
mypassword

두 명령 모두 입력을 다음과 같이 처리합니다.목록분리된 =.

답변3

이 시도:

sed -n "s/.*DB_PASS=\(.*\)/\1/p" <<< $(cat /root/dadosDB)

행이 하나만 있는 경우 ->

echo "DB_USER=myusername DB_PASS=mypassword DB_NAME=mydatabase" | sed -n "s/.*DB_PASS=\(.*\)DB.*/\1/p"

관련 정보