다음 형식의 파일이 많이 있습니다.
2014-11-19.8.ext
2014-11-26.1.ext
2014-11-26.2.blah.ext
2014-11-26_3.ext
2014-11-26.4.stuff_here.ext
2014-12-03.1. could be anything.ext
2014-12-032b.ext
2014-11-26 613 adva.ext
내 목표는 전체 파일 목록을 반복하여 날짜 형식을 가져와 추가 처리를 위해 YYYY-MM-DD
변수에 저장하는 것입니다 (내 경우에는 명령 YYYYMMDD
에 푸시됩니다 ).touch
따라서 일반적으로 다음 정규식과 일치합니다.(\d{4})-(\d{2})-(\d{2}).*
그런 다음 를 사용하여 원하는 패턴을 얻었지만 / 에서 이 작업을 수행하는 $1$2$3
방법을 잘 모르겠습니다 .bash
zsh
쉘 스크립트에서 이를 어떻게 수행할 수 있습니까?
답변1
사용매개변수 확장
$ touch 2014-11-19.8.ext 2014-11-26.1.ext
$ for f in *.ext; do d="${f:0:4}${f:5:2}${f:8:2}"; echo "$d"; done
20141119
20141126
${f:0:4}
변수명인 index부터 시작하여 4자를 나타냅니다0
.f
echo "$d"
귀하의 코드로 바꾸십시오 .
답변2
현재 디렉터리의 각 파일을 반복하고 파일 이름을 원하는 패턴과 비교하려면 날짜 조각이 포함된 변수를 설정하세요.
for f in *
do
[[ $f =~ ^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])(.*) ]] &&
yourvar="${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
done
이는 다음을 사용합니다.[[
정규식 일치를 사용하는 bash 기능날짜 조각을 BASH_REMATCH 배열에 넣습니다.
답변3
다음 명령을 사용하여 대화식으로 이 작업을 수행할 수 있습니다 GNU sed
.
$ sed 's/^\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}.*\)/\1\2\3/g' stuff.txt
여러 파일의 경우(동일한 디렉터리에 있고 해당 디렉터리에 고려되는 다른 파일이 없는 경우):
for file in *
do
if [ -f "$file" ]
then
sed 's/^\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\).*/\1\2\3/g' "$file"
fi
done
답변4
GNU Coreutils를 사용하면 다음이 표시됩니다.
$ date --date=2014-11-13 +"%Y%m%d"
20141113
하지만:
$ date --date=2014-11-130ABCJUNK +"%Y%m%d"
date: invalid date ‘2014-11-130ABCJUNK’
따라서 작업은 훨씬 간단합니다. YYYY-MM-DDetc
각 파일 이름의 처음 10자를 추출하여 날짜 자체를 얻은 다음 이를 date
다시 포맷하는 데 전달합니다.
그러나 GNU Coreutils를 사용하는 경우 정확히 동일한 옵션이 있으므로 해당 date
명령을 건너뛸 수 있습니다 .touch
--date=STRING
for file in * ; do
date=${file%${file##??????????}} # chop all but first ten
touch --date=$date -- "$file"
done
touch
그런데 GNU Coreutils에 의존할 때 POSIX 이식 가능한 방식으로 10자 슬라이싱을 수행하는 이유는 무엇입니까?
for file in * ; do
date=${file:0:10}
touch --date=$date -- "$file"
done