2009-07-24 5 views
3
bash-3.2$ sed -i.bakkk -e "s#/sa/#/he/#g" .* 
sed: .: in-place editing only works for regular files 

폴더의 모든 도트 파일에서 모든/sa/with/he /를 바꾸려고합니다. 어떻게 작동시킬 수 있습니까?홀수 Sed 오류 메시지

답변

7

사용 find -type f 이름 .* 일치하는 경우에만 파일을 찾아 디렉토리를 ...를 제외합니다. -maxdepth 1find이 하위 디렉토리로 재귀하는 것을 방지합니다. 그런 다음 -exec을 사용하여 sed 명령을 실행하고 {} 자리 표시자를 사용하여 파일 이름의 위치를 ​​find에게 알려줄 수 있습니다. 그것은 공백 또는 줄 바꿈 — 예를 들어 이상한 파일 이름에조차 작동 겠지만 -exec를 사용하여 사용하여 역 따옴표 또는 xargs 이상이 바람직하다

find . -type f -maxdepth 1 -name '.*' -exec sed -i.bakkk -e "s#/sa/#/he/#g" {} + 

"foo bar\nfile"가 유효한 파일 이름입니다. 선외 가작은 find -print0 | xargs -0

find . -type f -maxdepth 1 -name '.*' -print0 | xargs -0 sed -i.bakkk -e "s#/sa/#/he/#g" 

으로 동등하게 안전합니다. 파일 이름이 끝에 오는 명령 (실제로는 99 %)에서만 작동하기 때문에 좀 더 자세한 설명과 유연성이 있습니다.

+0

+ 끝에? 그것은 ";"와 동일합니까? ? –

+1

";" 파일 당 명령을 한 번 실행하므로 10 개의 파일에 대해 10 개의 명령이 실행됩니다. "+"는 파일의 * all *을 한 번 실행 한 후 10 개의 파일에 대해 1 개의 sed로 실행합니다. –

+0

"rm. *"과 같은 명령은 점 파일을 제거하는 것이 안전하지 않습니까? 당신이 원하는 : find. -name ". *"-exec rm '{}'\; ? –

1

글로브 패턴 .*에는 특수한 디렉토리 ...이 포함되어 있습니다.이 패턴은 사용자의 패턴에 포함시키지 않았을 가능성이 큽니다. 이 모든 디렉토리를 무시해야

sed -i.bakkk -e "s#/sa/#/he/#g" `find .* -type f -maxdepth 0 -print` 

(예를 들어,에서 .elm, .pine :

sed -i.bakkk -e "s$/sa/#/he/#g" $(ls -d .* | grep -v '^\.\|\.\.$') 
+2

+1. 추천 찾기/xargs : 찾기. -t f - 최대 깊이 1 - 이름 '. *'| xargs sed ... – pilcrow

2

이 하나를 시도 : 내가 그들을 제외하는 우아한 방법을 생각할 수 없다, 그래서 여기에 우아 방법 , .mozilla)뿐만 아니라. 그리고 .. 다른 해결책이 잡히지 않는다고 생각합니다.