[sed] 여러 파일 변경

다음 명령은 2 개의 파일 내용을 올바르게 변경합니다.

sed -i 's/abc/xyz/g' xaa1 xab1

그러나 내가해야 할 일은 여러 파일을 동적으로 변경하는 것이며 파일 이름을 모릅니다. I로 시작하는 현재 디렉토리의 모든 파일을 읽어들이는 명령을 쓰고 싶어 xa*하고 sed파일 내용을 변경해야합니다.



답변

더 나은 아직 :

for i in xa*; do
    sed -i 's/asd/dfg/g' $i
done

파일이 몇 개인 지 아무도 모르기 때문에 명령 줄 제한을 위반하기 쉽습니다.

파일이 너무 많으면 어떻게됩니까?

# grep -c aaa *
-bash: /bin/grep: Argument list too long
# for i in *; do grep -c aaa $i; done
0
... (output skipped)
#


답변

-exec 인수를 언급 한 사람이 아무도 없습니다.이 유형의 유스 케이스에 적합하지만 각 일치하는 파일 이름에 대해 프로세스를 시작합니다.

find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} \;

또는 xargs를 사용하여 더 적은 수의 프로세스를 호출 할 수 있습니다.

find . -type f -name 'xa*' | xargs sed -i 's/asd/dsg/g'

또는 find가 서브 프로세스 호출 당 둘 이상의 파일을 제공 할 수 있도록 find 대신 + exec 변형을 사용하십시오 ;.

find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} +


답변

grep과 sed를 함께 사용할 수 있습니다. 하위 디렉토리를 재귀 적으로 검색 할 수 있습니다.

Linux: grep -r -l <old> * | xargs sed -i 's/<old>/<new>/g'
OS X: grep -r -l <old> * | xargs sed -i '' 's/<old>/<new>/g'

For grep:
    -r recursively searches subdirectories
    -l prints file names that contain matches
For sed:
    -i extension (Note: An argument needs to be provided on OS X)


답변

이러한 명령은 sedMac OS X과 함께 제공 되는 기본값에서는 작동하지 않습니다.

보낸 사람 man 1 sed:

-i extension
             Edit files in-place, saving backups with the specified
             extension.  If a zero-length extension is given, no backup
             will be saved.  It is not recommended to give a zero-length
             extension when in-place editing files, as you risk corruption
             or partial content in situations where disk space is exhausted, etc.

시도

sed -i '.bak' 's/old/new/g' logfile*

for i in logfile*; do sed -i '.bak' 's/old/new/g' $i; done

둘 다 잘 작동합니다.


답변

@PaulR 은 이것을 의견으로 게시했지만 사람들은 그것을 답변으로보아야합니다 (그리고이 답변은 내 요구에 가장 적합합니다).

sed -i 's/abc/xyz/g' xa*

이것은 아마도 수십 개 정도의 파일은 적당하지만 수백만 개 정도는 아닐 것입니다 .


답변

또 다른 다목적 방법은 다음을 사용하는 것입니다 find.

sed -i 's/asd/dsg/g' $(find . -type f -name 'xa*')


답변

find비슷한 작업에 사용 하고 있습니다. 매우 간단합니다. 다음 sed과 같은 인수로 전달해야 합니다.

sed -i 's/EXPRESSION/REPLACEMENT/g' `find -name "FILE.REGEX"`

이렇게하면 복잡한 루프를 작성할 필요가 없으며 변경할 파일이 무엇인지 쉽게 알 find수 있습니다 sed. 실행 하기 전에 실행하십시오 .