여러 줄이 포함된 파일이 있습니다. 특정 패턴 뒤에 나타나는 문자열을 얻으려고 합니다...
이것은 내가 실행하려는 명령입니다.
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)"
개행 문자는 유지됩니다.
핵심은
cat
명령 대체를 원하지도 요구하지도 않습니다 .- 큰따옴표를 넣지 않고 명령 대체를 사용하면 개행 문자가 손실됩니다(참조:이 질문과 답변의 예). (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"