디렉토리 아래의 다음 파일에서 포트 번호를 얻고 싶습니다 Variable
. 파일의 포트 라인이 비어 있으면 i가 grep:
인쇄됩니다. 이를 무시하고 아무것도 인쇄하지 않는 방법이 있습니까?
if ls $directory/*.domain.*.properties 1>/dev/null 2>&1; then
port=$(grep "domain.http.listener.port=" $directory/*.domain.*.properties |
awk -F "=" 'NR==1{print $NF}' | tr -d "\r")
fi
답변1
domain.http.listener.port=
귀하의 코드는 여러 파일에서 가 포함된 표현식을 찾는 것으로 보이며 grep
, awk
명령은 해당 결과의 첫 번째 줄에서 마지막으로 =
구분된 필드만 인쇄한 다음 결과에서 캐리지 리턴을 제거합니다.
불필요한 ls
. 파일 이름 globbing 패턴이 일치하는지 테스트하기 위해 이것을 사용하는 것으로 보입니다 $directory/*.domain.*.properties
(아마도 공백의 값을 분할 $directory
하고 해당 비트에 대해 파일 이름 globbing을 수행할 수도 있음).
파일 이름 와일드카드 패턴이 파일 이름과 일치하는지 테스트하려면 다음을 사용할 수 있습니다.
set -- "$directory"/*.domain.*.properties
directory
( 단일 디렉토리의 이름이나 경로 이름만 포함해야 한다고 가정했기 때문에 변수 확장을 인용했습니다 .)
if [ "$#" -gt 1 ] || [ -e "$1" ]; then ...; fi
이 set
명령은 위치 매개변수( $1
, 등) $2
를 설정하고 $3
이러한 매개변수를 여러 개(1보다 큼) 얻으면 $#
패턴이 여러 항목과 일치합니다. 또한 패턴이 단일 항목과 일치하면 를 사용하여 해당 항목이 존재하는지 테스트합니다 -e
. 마지막 테스트에서는 단일 일치와 비일치(패턴이 확장되지 않은 상태로 유지됨)를 구분합니다.
awk
grep
의 작업을 수행할 수 tr
있으므로 가지고 있는 파이프가 실제로 필요하지 않습니다.
awk -F '=' '/domain\.http\.listener\.port=/ { sub("\r","", $NF); print $NF; exit }'
그렇지 않으면 모든 문자와 일치하기 때문에 정규식에서 점을 이스케이프 처리합니다. 여기서는 다른 곳이 아닌 줄 끝에서 캐리지 리턴을 제거하려고 한다고 가정하기 때문에 여기서 만 sub()
대신 사용합니다.gsub()
모든 것을 한 번에:
#!/bin/sh
set -- "$directory"/*.domain.*.properties
if [ "$#" -gt 1 ] || [ -f "$1" ]; then
awk -F '=' '/domain\.http\.listener\.port=/ { sub("\r","", $NF); print $NF; exit }' "$@"
fi
다른 것보다 일반 파일(또는 심볼릭 링크)에서 실행하는 것이 더 합리적이기 때문에 -e
테스트를 테스트로 변경했습니다 ( 그러나 일치하는 항목이 여러 개인 경우 어떤 파일의 파일 형식도 테스트하지 않습니다).-f
awk
"$@"
패턴이 명령에서 일치하도록 관리하는 모든 이름(개별적으로 인용됨) 으로 확장됩니다 .set
첫 번째 일치 항목이 포함된 파일의 경로 이름을 원하는 경우 이를 수정하여 특수 변수 (예 : ) awk
의 내용도 인쇄 할 수 있습니다 . 당신이 원하는FILENAME
print FILENAME, $NF
모두(첫 번째 파일의 첫 번째 일치뿐만 아니라) 일치한 다음 exit
.
파일 이름 와일드카드 패턴(귀하의 것과 같은)과 일치하는 파일이 수백 또는 수천 개 있는 경우 이 해결 방법은 실패합니다. 이 경우 쉘 루프를 실행할 수 있습니다:
for pathname in "$directory"/*.domain.*.properties; do
if [ -f "$pathname" ]; then
awk -F '=' '
/domain\.http\.listener\.port=/ {
sub("\r","", $NF); print $NF; found=1; exit
}
END { exit !found }' "$pathname" && break
fi
done
여기에서는 원하는 텍스트를 인쇄하는 동안 종료 상태가 0인 상태로 종료하도록 선택했는데 awk
, 이로 인해 루프가 종료됩니다.