내 요구 사항은 쉘 스크립트가 파일의 폴더 이름을 인쇄해야 한다는 것입니다.
예를 들어 comp.class는 D:/Practice/HelloWorldPractice/bin 폴더에 있습니다. 명령을 실행한 후 출력을 얻어야 합니다.쓰레기통.
내 명령은 파일을 검색하고 파일의 전체 경로를 인쇄합니다. 그런 다음 전체 경로에서 파일 이름을 제거합니다. 마지막으로 파일의 폴더 이름을 제외한 모든 항목을 삭제합니다.
암호
filesDirName="/D/Practice/HelloWorldSagar"
file=comp.class
echo $(find "${filesDirName}" -name ${file}) | awk -F '${file}' '{ print $1 }'| awk -F '${filesDirName}' '{ print $2 }'
산출 빈 출력
암호
터미널에 다음 명령을 입력하면 제대로 작동하지만 변수를 통해 수행하면 출력을 얻을 수 없습니다.
echo "$(find "/D/Practice/HelloWorldSagar" -name comp.class)" | awk -F 'comp.class' '{ print $1 }'| awk -F '/D/Practice/HelloWorldSagar' '{ print $2 }'
산출
/쓰레기통/
답변1
for를 필드 구분 기호로 사용하는 것 comp.class
(또는 코드에서 변수 확장을 작은따옴표로 묶는 것)은 파이프라인에서 여러 프로그램을 서로 실행하는 awk
것처럼 나에게는 별로 의미가 없습니다 .awk
내가 이해한 바로는 comp.class
파일이 포함된 디렉터리의 파일 이름이 필요합니다.
수행 방법은 다음과 같습니다.
topdir='/D/Practice/HelloWorldSagar'
filename='comp.class'
find "$topdir" -type f -name "$filename" \
-exec sh -c 'basename "$(dirname "$1")"' sh {} ';'
comp.class
그러면 에서 또는 그 아래에서 호출되는 모든 파일을 찾습니다 /D/Practice/HelloWorldSagar
. 경로 이름이 발견되면 짧은 쉘 스크립트는 발견된 경로 이름에 대한 디렉토리 경로의 기본 이름(경로 이름의 파일 이름 부분)을 간단히 인쇄합니다.
또는 디렉터리를 찾아 파일이 있는지 개별적으로 테스트합니다.
find "$topdir" -type d \
-exec test -f {}/"$filename" ';' \
-exec basename {} ';'
comp.class
$topdir
이것은 자신을 포함하여 발견된 모든 디렉토리에 존재하는지 테스트합니다 $topdir
. 파일이 발견되면 발견된 디렉토리의 기본 이름이 인쇄됩니다.
두 방법의 차이점은 두 번째 방법도 감지한다는 것입니다.심볼릭 링크comp.class
일반 파일을 가리키는 호출됩니다 .
관련된:
원하는 디렉토리의 기본 이름이 아니라 아래의 상대 경로인 경우를 대비해 다음과 같이 하십시오 $topdir
.
find "$topdir" -type f -name "$filename" \
-exec sh -c 'd="$(dirname "$2")"; printf "%s\n" "${d#$1/}"' sh "$topdir" {} ';'
d
이는 디렉터리 이름을 변수로 추출한 다음 해당 디렉터리 경로 이름의 값을 $topdir
처음부터 제거하여 인쇄 하는 첫 번째 솔루션의 변형입니다 .