나는 다음을 수행하려고합니다.
find . -name "*.dat" | get the basename of file | move filename returned by first command to basename returned by second command
./mydir1/dir2/file1.dat
구체적인 예를 들자면 이름을 로 바꾸고 싶습니다 file1.dat
.
파이프로 할 수 있나요? 그렇다면 첫 번째 명령의 출력을 첫 번째 파이프의 변수에 저장하고 두 번째 파이프에서 어떻게 사용할 수 있습니까? "파이프라인"이라는 용어를 올바르게 사용했으면 좋겠습니다.
답변1
find 명령이 이 작업을 자체적으로 수행하므로 파이프가 필요하지 않습니다.
find . -name "*.dat" -exec mv -t . {} \;
.dat
현재 디렉토리에 이미 있는 파일도 찾아서 이동하므로 이는 다소 비효율적입니다 .
답변2
파이프라인의 "수평적" 환경에는 실제로 영향을 미칠 수 없습니다. ... p_n | p_n+1 | p_n+2 ...
파이프라인의 프로세스는 동일한 셸 해석기에 의해 생성되므로 환경 변수를 변경할 수 없습니다. 예를 들어 p_n
echii p_m
는 동일한 파이프라인에 있습니다.
파일 이름의 간단한 변환(정규식을 사용하여 수행할 수 있음)이 필요한 경우 다음을 수행하십시오.펄 예rename
해야 할 것. 다음을 사용하여 xargs
이스케이프 문제를 방지 하고 싶거나 필요할 수 있습니다.
find ... -print0 | xargs -0 rename "regexps"
NUL 바이트를 사용하여 파일 이름을 구분합니다(NUL과 백슬래시는 일반적으로 파일 이름에 표시되는 것이 금지된 유일한 문자입니다).
파일 이름이 제대로 작동한다면(따라서 정규 표현식에 사용되는 따옴표, 공백 및 구분 기호와 같은 특별한 "이상한" 문자 이스케이프가 필요하지 않다고 가정할 수 있음) 다음과 같은 빠르고 더러운 작업을 수행할 수도 있습니다.
find ... | sed -r "regexps" | sh -
이 경우 정규식은 유효한 명령 호출 mv
(또는 필요한 작업을 수행하는 다른 명령)을 생성해야 합니다. 이는 다음과 같습니다.
"s|^.*$|mv -vi & &.old|"
이것은 다음과 같은 것을 생성합니다
...
mv -vi /etc/a2ps.cfg /etc/a2ps.cfg.old
mv -vi /etc/aclocal_dirlist /etc/aclocal_dirlist.old
...
간단한 정규 표현식이 충분히 강력하지 않은 경우그렇지 않으면 너무 많은 문제가 될 것입니다, 파일 이름을 처리하고 자체적으로 이름을 바꾸거나 이동하는 간단한 스크립트를 작성한 다음 find ( -exec
또는 ) 또는 .find 를 통해 직접 -exec +
호출하십시오 xargs
.
마지막으로, 여러 파일의 복사본을 다른 디렉터리로 이동하려면 및 -t
옵션을 사용하세요. GNU coreutils에는 소스와 전체 경로를 복사하는 옵션도 있습니다.cp
mv
cp
--parents
답변3
가능한 가장 강력한 방법으로 실제 문제를 해결하려면 다음을 수행하십시오.
경고: 명령줄이 매우 깁니다.
find "${directory:-.}" -type f -name "*.dat" -exec sh -c 'for dat; do
if [[ -e $dat ]]; then
base_fn=${dat%.*}$((++n)).dat
base_fn=${dat##*/}
else
base_fn=${dat##*/}
fi
mv "$dat" "$base_fn"
done' _ {} +
이것은 이식 가능합니다.POSIX이는 실제로 -exec ... {} +
가장 일반적인 용도를 대체하도록 지정되었습니다 xargs
. 내 생각엔 GNU에 특화된 것들이 mv -t
좋은 것 같아요. 유일한 주의 사항은 GNU가 없으면 각 파일에 대해 새 프로세스를 생성 mv -t
해야 한다는 것입니다.mv
반면에 디렉터리 구조를 평면화하면 동일한 기본 이름을 가진 파일이 손상될 수 있습니다. 내 접근 방식은 가장 극단적인 경우를 제외하고는 이를 피할 것입니다(ARG_MAX가 저장할 수 있는 것보다 더 많은 파일이 있는 경우,그리고두 번째 호출에서는 다음 sh
위치에 있는 또 다른 중복된 기본 이름을 발견합니다.첫 번째전화하면 첫 번째 전화를 잃게 됩니다. )아 그렇군요. 이는 코딩하기 어려운 극단적인 경우입니다.