sed가 교체하기 전에 확인을 요청합니까?


37

sed가 교체하기 전에 확인을 요청하는 방법이 있습니까? vim 내부에서 replace를 사용할 때 'c'와 비슷한 것.

sed는 이것을 전혀하지 않습니까?


3
기술적으로 가능하지만 유용한 노력보다 지적 운동이 더 많습니다. 큰 폴더 계층 구조에서 텍스트를 바꾸는 방법을 참조하십시오 . Vim 및 Perl 솔루션이 있습니다.
Gilles 'SO- 악한 중지'

나는 오전 에 '간단한'방법을 정력 (인수 및 argdo)를 사용하여 나는 '확인'을해야 할 때마다,하지만이 있다면 궁금 해서요
Yuvi

1
스트림을 통한 편집을 자동화하는 sed의 기본 목적에 위배됩니다.
teppic

@teppic은 실제로 텍스트 파일에서 인스턴스를 찾아야 하기 때문에 실제로는 아닙니다 .sed 는 당신을 위해 할 수 있습니다. 목록에 잘못된 파일을 추가하고 편집중인 파일을보고 싶을 경우를 대비하여 질문이 의미가 있다고 생각합니다.
Kolob Canyon

답변:


37

그것을 이렇게하면 sed은 대화 형이 아닌 스트림 편집자로 아마 불가능했을 것입니다. 포장 sed스크립트에서하는 것은 너무 많은 생각을 필요로한다. 다음과 vim같이 하는 것이 더 쉽습니다 .

vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' file.in

아래 주석에서 언급되었으므로 현재 디렉토리의 특정 파일 이름 globbing 패턴과 일치하는 여러 파일에서 사용되는 방법은 다음과 같습니다.

for fname in file*.txt; do
    vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done

또는 대체를 수행하기 전에 파일에 주어진 패턴과 일치하는 행이 실제로 있는지 확인하려는 경우,

for fname in file*.txt; do
    grep -q 'PATTERN' "$fname" &&
    vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done

위의 두 셸 루프 findtop-dir디렉토리 내 또는 디렉토리 아래에 특정 이름을 가진 모든 파일에 대해 동일한 작업을 수행하는 명령으로 수정되었습니다 .

find top-dir -type f -name 'file*.txt' \
    -exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
find top-dir -type f -name 'file*.txt' \
    -exec grep -q 'PATTERN' {} \; \
    -exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;

또는 원래 쉘 루프를 사용하고 find피드 경로 이름을 지정하십시오.

find top-dir -type f -name 'file*.txt' -exec sh -c '
    for pathname do
        vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
    done' sh {} +
find top-dir -type f -name 'file*.txt' -exec sh -c '
    for pathname do
        grep -q "PATTERN" "$pathname" &&
        vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
    done' sh {} +

어쨌든 당신은 그 이후로 무언가를하고 싶지 않습니다.for filename in $( grep -rl ... )

  1. 그것은 그 필요 grep도있다 루프의 첫 번째 반복, 시작하기 전에 실행 완료 우아를 하고,
  2. 반환 된 경로 이름 grep은 공백에서 단어로 분리되며이 단어는 파일 이름을 붙입니다 (공백과 특수 문자가 포함 된 경로 이름을 제외합니다).

관련 :


2
sed예를 들어 여러 파일에서 작동 할 수 있다는 장점 이 있습니다 sed -i 's/old/new/g' /path/to/*.txt.
user1717828

10
for i in $(grep -rl "old"); do vim -c "%s/old/new/gc" -c "wq" "$i"; done
tcpaiva

@ tecepe, 답변으로 변환하십시오, 감사합니다.
Nishant

1
@Nishant 이름이나 경로에 공백이 포함 된 파일을 실격 처리하므로 깨지기 쉬운 대답입니다.
Kusalananda

7

다음과 같이하면 얻을 수 있습니다.

:%s/OLD_TEXT/NEW_TEXT/gc

특히 c세 번째 구분 기호 뒤에를 추가하십시오 .

'c'옵션은 Vim에서만 작동합니다. sed명령 행에서 사용할 수 없습니다 .


4
명확히하기 위해 : 이것은 정규 명령 줄이 아닌 Vim에서만 작동합니다 sed.
Brendan

OP에 태그가 붙어 있으므로이 vim답변이 적용됩니다. 그러나, vim과 sed는 다른 능력을 가지고 있습니다
ILMostro_7


-1
searchandreplace () {
if [ -z $2 ] ; then
    realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
else
    realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
    exp=$(realpath * | xargs grep -ins --directories=skip --color=never "$1" | cut -d':' -f1,2 | awk -F':' '{print $2 $1}' | sed -E "s|^[0-9]+|sed -i \'&s/|; s|//|/"$1"/"$2"/g\' /|")
    IFS=$'\n'
    for d in $exp
        do
        read -p "Exec $(echo -e -n "\033[1;31m$d\033[0m")? " -e REP
            if [ "$REP" = y ]; then
            echo `bash -c $d`;
            fi
    done
fi
}

이것을 단일 인수로 공급하면 – searchandreplace "AAA"현재 디렉토리에서 해당 문자열 만 검색하지만 이중 인수로 공급하는 경우 – searchandreplace AAA BBB위의 것 외에도 첫 번째를 두 번째 "행으로 대체하도록 요청합니다" 모든 줄에 대해

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