아르카나 발견: -exec 라인에서 파이프가 작동하도록 할 수 없습니다

아르카나 발견: -exec 라인에서 파이프가 작동하도록 할 수 없습니다

sed를 통해 조회 결과를 xform 스트림으로 파이프한 다음 변환된 스트림을 스크립트에 대한 두 인수 중 하나로 사용하려면 어떻게 해야 합니까? 즉:

찾다file1.tiff(및 기타 파일)가 나타납니다.
sedfile1.tiff --> file1.jpg를 변환
하고 다음 두 매개변수를 사용하여 명령을 실행합니다.file1.tiff file1.jpg 변환

여러 가지 방법을 시도했지만 얻을 수 없습니다. 풍미를 더하려는 시도는 다음과 같습니다.

find ./out -regex ".*_p[bg]_.*tiff" -exec echo "Processing {}" \; -exec convert {} `echo {} | sed s/tiff/jpg/` \;

이런 부분들을 따로 하려고 포기하고 파이썬 스크립트를 작성했어야 했는데 결국 유닉스 도구를 배우려고 하다가 지금은 푹 빠져있습니다. 돕다!

답변1

거기에 파이프가 있을 수 있는지 확실하지 않습니다 -exec. find -exec echo {} \| sed s/tiff/jpg \;작동하지 않는 것 같습니다.

가장 좋은 옵션은 변환을 수행하는 스크립트를 만드는 것입니다.

변환_tiff_to_jpg:

#!/bin/bash
echo "Processing $1"
convert "$1" "${1/%tiff/jpg}"

find -exec예상대로 호출하세요.

find ./out -regex ".*_p[bg]_.*tiff" -exec convert_tiff_to_jpg {} \;

이를 수행하는 데 사용할 수 있는 여러 가지 방법이 있지만 find -print0 | xargs -0모두 매우 보기 흉합니다.

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
while IFS= read -d $'\0' -r filename; do
    echo "Processing $filename"
    convert "$filename" "$(echo "$filename" | sed 's/tiff$/jpg/')"
done

또는

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
while IFS= read -d $'\0' -r filename; do
    echo "Processing $filename"
    convert "$filename" "${filename/%tiff/jpg}"
done

또는

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
    xargs -0 -I FILE bash -c 'F="FILE"; echo "$F" "${F/%tiff/jpg}"'

참고로 파일명의 끝이 아닌 다른 곳에 나타나면 변경 되지 s/tiff/jpg않도록 변경했습니다 .s/tiff$/jpgtiff

답변2

에 쉘 명령을 전달하려고 하는데 -exec프로그램 이름과 매개변수 목록이 필요합니다. 따라서 쉘을 시작하도록 명시적으로 지시해야 합니다.

find ./out -regex ".*_p[bg]_.*tiff" \
     -exec sh -c 'echo "Processing $0"; convert "$0" "${0%.tiff}.jpg"' {} \;
  • sh -c 'shell code, not using single quotes'이는 인수가 있는 명령의 컨텍스트에서 셸 기능이 필요할 때 비교적 일반적인 관용어입니다.
  • -exec sh -c 'do stuff with "$0"' {} \;find쉘과 관련된 관용적 표현 입니다 . 일부 버전의 find에서는 {}쉘 코드에 직접 쓰기를 허용하지만 이는 좋지 않은 생각입니다. 일부 버전의 find에서는 이를 허용하지 않을 뿐만 아니라 파일 이름에 특수 문자(예: 따옴표)가 포함되어 있으면 혼란을 초래할 수 있기 때문입니다. 따라서 파일 이름은 0번째 인수로 셸에 전달되고 스크립트는 셸 변수를 사용하여 $0파일을 참조합니다.
  • echo tiff_filename | sed s/tiff/jpg/파일 이름을 변경하는 복잡하고 비효율적이며 부정확하고 취약한 방법입니다. sed를 호출하기 때문에 복잡하고 비효율적입니다. tiff파일의 아무 곳이나 바꾸려고 하기 때문에 이는 잘못된 것입니다 . 예 tiffany.tiff를 들어 일부 파일 이름( 일부 맹글 백슬래시 구현) jpgany.tiff에서는 작동하지 않기 때문에 취약합니다 . echo대신 파일 이름에서 접미사를 ${0%.tiff}제거 하세요 ..tiff$0

관련 정보