찾기 명령 출력에서 ​​경로 제거


29

베타 환경에서 프로덕션 환경으로 코드를 배포하기위한 bash 스크립트가 있지만 현재는 파일 목록을 txt 파일에 수동으로 추가해야하며 때로는 누락되었습니다. 기본적으로 내 배포 스크립트는 파일을 복사하는 cat / loops입니다. (DB 내보내기 / 가져 오기도 있지만 관련이 없습니다 ..lol)

어쨌든 find지난 14 일 동안 수정 된 파일 목록을 생성하기 위해이 명령 을 사용하고 싶습니다 . 문제는 ./배포 스크립트가 작동하려면 경로를 제거해야 한다는 것입니다.

find 명령 사용법의 예는 다음과 같습니다.

찾기 -f f -mtime -14> deploy.txt를 입력하십시오.

deploy.txt내 배포 스크립트에 나오는 줄은 다음과 같습니다 .

for i in `cat deploy.txt`; do cp -i /home/user/beta/public_html/$i /home/user/public_html/$i; done

bash 스크립팅을 사용하여이를 수행하는 방법에 대한 아이디어가 있습니까?

감사!


3
rsync를 사용할 수없는 이유가 있습니까? 마치 바퀴를 재발 명하고 삼각형으로 만들려고하는 것처럼 들립니다.
ThatGraemeGuy 2016 년

그러나 배포하기 전에 유효한 포인트 deploy.txt를 검토하고 수정이 필요한 항목이 제거됩니다.
Mikey1980

1
rsync를 --dry-run모드 에서 실행 하고 검토를 위해 파일로 출력합니까?
Zoredache

답변:


36

-printf명령 행 옵션을 사용하여 %f디렉토리 정보없이 파일 이름 만 인쇄 할 수 있습니다.

find . -type f -mtime -14 -printf '%f\n' > deploy.txt

또는 sed를 사용하여 ./

find . -type f -mtime -14 | sed 's|^./||' >deploy.txt

나는 당신이 탈출해야한다고 생각합니다 /..
EEAA

5
|구분자로 사용할 때는 아닙니다 .
user9517은 GoFundMonica를 지원합니다.

3
를 사용 %f하면뿐만 아니라 모든 디렉토리가 제거됩니다 ./. 반환 된 파일 find이 하위 디렉토리에있는 경우 배포 스크립트가 중단됩니다 .
James Sneeringer

2
@Iain 당신은 .비록 탈출해야합니다 . 그리고 아마도 라인 시작 앵커를 사용하는 것이 가장 좋습니다 :s|^\./||
James O'Gorman

12
%P대신에 사용하십시오 %f. 이것은 명령 행에 주어진 경로를 차단합니다.
TrueY

11

./무해해야한다. 대부분의 프로그램은 취급 /foo/bar/foo/./bar같은 동등한. 나는 그것이 멋지게 보이지는 않지만 당신이 게시 한 것을 기반으로 스크립트가 실패하는 이유를 알 수 없습니다.

정말로 그것을 제거하고 싶다면 sed가장 깨끗한 방법 일 것입니다.

find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt

GNU find가있는 시스템 (예 : 대부분의 Linux 시스템)을 사용하는 경우 다음을 사용하여 한 번에 수행 할 수 있습니다 find -printf.

find . -type d -mtime 14 -printf "%P\n" > deploy.txt

%P명령은 찾은 각 파일의 전체 경로에서 명령 행에 지정된 경로에서 첫 번째 슬래시까지의 경로를 뺀 값을 반환합니다. 그러면 디렉토리 구조의 모든 하위 디렉토리가 유지됩니다.


1
./접두사는 실제로 기능입니다; 그렇지 않으면 대시로 시작하는 파일 이름 등 다른 명령으로의 파이프 출력이 올바르게 작동하지 않습니다.
tripleee

1
@tripleee-유틸리티의 유용성을 이해했지만 OP는 배포 스크립트에 문제를 일으켜서 제거하는 방법을 구체적으로 요청했습니다. 물론, 그가해야 할 일을하는 더 좋은 방법이 있을지 모르지만, 그것은 요청 된 것의 범위를 넘어선 토끼 구멍입니다.
James Sneeringer

7

왜 벗겨야 ./합니까? 경로에있는 것이 유효합니다. 그래서

cp -i dir1/./somefile dir2/./somefile

그냥 괜찮아!

그러나 find에서 디렉토리 이름을 제거하려면 %Parg를 사용할 수 있습니다 -printf.

남자 찾기 (1)의 말 :

         %P     File's name with the name of the  command  line  argument
                 under which it was found removed.

$ find other -maxdepth 1
other
other/CVS
other/bin
other/lib
other/doc
other/gdbinit
$ find other -maxdepth 1 -printf "%P\n"

CVS
bin
lib
doc
gdbinit

첫 번째 빈 줄을 생각하십시오! 사용을 피하려면-mindepth 1

$ find other -mindepth 1 -maxdepth 1 -printf "%P\n"
CVS
bin
lib
doc
gdbinit

3

몇 가지 옵션이 있습니다. -printffind 에서 옵션을 사용하여 파일 이름 만 인쇄하거나 sed와 같은 도구를 사용하여 단순히 파일을 제거 할 수 있습니다 ./.

# simply print out the filename, will break if you have sub-directories.
find . -mtime -14 -printf '%f\n'

# strip a leading ./
find .  -mtime -14 | sed -e 's/^\.\///'

그 사용법을 예를 들어 주시겠습니까? 죄송합니다, 리눅스는 실제로 제
요새

2
다시 한번 살펴보십시오. 예가 있습니다.
Zoredache

동의-그냥 시도해보십시오, 당신은 찾기와 sed의 조합을 실행하는 것을 해치지 않을 것입니다.
EEAA

3

find에는 그러한 옵션이 없기 때문에 "find -printf"솔루션은 FreeBSD에서 작동하지 않습니다. 이 경우 AWK가 도움이 될 수 있습니다. 성 ($ NF)을 반환하므로 모든 깊이에서 작동 할 수 있습니다.

find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}'

추신 : D.Tansley "Linux and Unix shell programming"책에서 발췌


2

질문을 올바르게 이해하면 빠른 해결책 cutfind명령 의 출력을 사용 하는 것입니다 .

$> find . -type f -mtime -14 | cut -b 3- > deploy.txt

결과의 각 줄에서 첫 번째 문자를 제거합니다 (귀하의 경우 ./). 아마도 최상의 솔루션은 아니지만 시나리오에서 작동합니다.


1

sed 이런 종류의 일에 완벽합니다.

$ find . -type f -mtime -14 find . | sed 's/^\.\///' > deploy.txt

1

우리가 어떤 종류의 파일 이름을 말하고 있는지 알지 못하지만 공백이나 줄 바꿈이 있으면 대부분의 솔루션이 위험에 처하게됩니다.

내 제안은 쉘의 매개 변수 확장을 사용하여 각 파일 이름에서 문자를 제거하는 것입니다.

find . -mtime -14 -exec sh -c 'printf "${0#./}\n"' {} \; >deploy.txt

파이프를 정말로 좋아한다면, xargs와 함께 널과 같은 "안전한"구분 기호를 사용하여 각 파일 이름을받을 수 있습니다.

find . -mtime -14 -print0 | xargs -0 -n 1 sh -c 'printf "${0#./}\n"' >deploy.txt

이 결과는 null로 구분 되지 않으므로 안구 검사에는 충분할 수 있지만 소스에 대해 확신이 없으면 이러한 솔루션 중 어느 것도 자동화에 사용하기에 안전한 deploy.txt 파일을 생성하지 않습니다. 파일 이름.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.