"echo"를 통해 얻은 출력은 터미널에 붙여넣을 때 명령으로 작동하지만 스크립트 내에서는 작동하지 않습니다.

"echo"를 통해 얻은 출력은 터미널에 붙여넣을 때 명령으로 작동하지만 스크립트 내에서는 작동하지 않습니다.

불행하게도 종종 공백이 포함된 응용 프로그램에서 생성된 파일을 변경하려고 합니다. 터미널에 복사하여 붙여 넣으면 작동하는 출력을 제공하기 위해 "에코"를 얻었지만 명령을 실행하려고 하면 작동하지 않습니다. 내가 찾고 있어요이것답변, 이전에는 도움이 되었지만 이 경우에는 "${x}" 구문도 작동하지 않는 것 같습니다.

#!/bin/sh
cd ~/Data
IFS=$'\n';for i in $(ls); do
    echo "$i";
    filename="$i"
    date=$(date -n +%Y-%m-%d)
    new_filename="$date$filename"
    echo mv \'"${filename}"\' \'"${new_filename}"\'
    mv \'"${filename}"\' \'"${new_filename}"\'
done;

답변1

주요 문제는 출력 ls명령을 반복한다는 것입니다. 글로브를 사용하세요 *:

#!/bin/sh
cd ~/Data
for i in *; do
    echo "$i"
    filename="$i"
    date=$(date -n +%Y-%m-%d)
    new_filename="${date}${filename}"
    echo mv "${filename}" "${new_filename}"
    mv -- "${filename}" "${new_filename}"
done

또한 이름을 올바르게 처리하기 --위해 추가했습니다 . 그런데 내 명령에는 옵션이 없지만 다른 버전이 있을 수 있으므로 그대로 두었습니다.mv-date-n

답변2

또 다른 문제는 mv 줄에 추가 따옴표가 있다는 것입니다. echo를 사용하여 쉘에 복사될 명령을 인쇄할 때 모든 것을 두 번 인용해야 합니다. 한 번은 이 쉘에 대해 한 번은 두 번째 쉘에 대해 인용해야 합니다. 파일 이름이 대시로 시작하지 않거나 작은따옴표를 포함하지 않는 한 echo mv는 제대로 작동합니다. mv는 한 번만 참조하면 됩니다.

코드 조각을 다시 작성하는 방법은 다음과 같습니다.

#!/bin/bash
cd ~/Data
date="$(date -n +%Y-%m-%d)"

for filename in *; do
    echo "${filename}"
    new_filename="$date$filename"
    filename_e="$(echo "$filename"|sed -e 's!\('\''\)!\\\1!')"
    new_filename_e="$(echo "$new_filename"|sed -e 's!\('\''\)!\\\1!')"
    echo mv -- \'"${filename_e}"\' \'"${new_filename_e}"\'
    mv -- "${filename}" "${new_filename}"
done;

이 버전은 이름에 문자가 포함된 모든 파일의 이름을 올바르게 변경합니다. 유일한 제한은 echoed 명령이 이름에 개행 문자가 포함된 파일에서 작동하지 않는 명령을 생성할 수 있다는 것입니다.

답변3

\공백 앞에 이스케이프 문자를 추가하여 파일 이름을 처리하면 됩니다 .

filename=$(echo $i|sed 's/ /\\ /g')
mv $filename $new_filename

관련 정보