Solaris에서 다음과 같이 원래 확장자를 유지하면서 이름의 현재 타임스탬프를 포함하여 폴더의 모든 파일 이름을 바꾸고 싶습니다.
test1.txt > test1.date.txt
이것을 시도했지만 이름의 첫 부분을 잃어버렸습니다.
find * -prune -type f -name '*.txt' -exec mv {} {}.$(date +'%Y%m%d%H%M').txt \;
내가 놓친 게 무엇입니까?
답변1
find . -type f -name '*.txt' -exec sh -c '
now=$( date +%Y%m%d%H%M )
for pathname do
mv "$pathname" "${pathname%.txt}.$now.txt"
done' sh {} +
이것은 이름이 로 시작하는 현재 디렉토리 안이나 아래에 있는 모든 일반 파일의 경로 이름을 찾습니다 .txt
. 일괄 처리를 위해 짧은 쉘 스크립트가 호출됩니다. 스크립트는 먼저 타임스탬프(효율성을 위해 배치당 한 번만)를 얻은 다음 지정된 경로 이름을 반복합니다.
각 경로 이름에 대해 마지막 경로 이름을 제거하고 .txt
( 사용 ) 점, 타임스탬프 및 를 추가하여 ${pathname%.txt}
이름이 변경됩니다 .txt
.
이는 Solaris에서 테스트되지 않았지만 표준 구성 요소 및 옵션 등만 사용합니다.
호출하기 전에 타임스탬프를 한 번만 계산하려면 find
다음을 사용하십시오 .
now=$( date +%Y%m%d%H%M ) \
find ...as before (but without assigning to now)...
또는
env now="$( date +%Y%m%d%H%M )" \
find ...as before (but without assigning to now)...
(위 두 명령의 줄 연속성에 유의하세요)
파일이 있는 경우하나의디렉터리에서 루프를 실행하면 됩니다.
now=$( date +%Y%m%d%H%M )
for pathname in ./*.txt; do
mv "$pathname" "${pathname%.txt}.$now.txt"
done
이는 패턴이 ./*.txt
이름을 바꾸려는 모든 이름과 일치한다고 가정합니다.
관련된:
당신의 것은 {}.$(date +'%Y%m%d%H%M').txt
휴대용으로 작동하지 않습니다. 의 일부 구현과 함께 사용될 수 있지만 다른 문자열이 있는 경우 현재 경로 이름으로 find
구현을 확장할 필요는 없습니다 .{}
{}
관련 텍스트의 출처는 다음과 같습니다.POSIX 표준은:
utility_name
두 문자만 포함하는 또는 매개변수는{}
현재 경로 이름으로 바꿔야 합니다.utility_name
또는 매개변수 문자열에 이 두 문자가 포함되어 있지만{}
이 두 문자만 포함되어 있지 않은 경우{}
find가 두 문자를 대체할지 또는 변경되지 않은 문자열을 사용할지 여부는 구현에 따라 정의됩니다..
답변2
solaris
또 다른 옵션은, 얼마나 호환되는지 잘 모르겠지만 ...
from=txt
to=$(date +%Y%m%d%H%M).txt
find * -prune -type f -name "*.$from" -exec sh -c 'mv "$3" "${3%.$1}.$2"' sh "$from" "$to" {} ';'
뻔뻔하게도unix.stackexchangesh
@Kulasananda가 링크를 제공했지만 호출이 구성된 변수로 나오는 방식이 마음에 듭니다 sh -c mv
.
달콤한.