각 대체 전에 sed가 확인을 요청하도록 하시겠습니까?

각 대체 전에 sed가 확인을 요청하도록 하시겠습니까?

각 대체 전에 sed가 나에게 확인을 요청하도록 하는 방법이 있습니까? vim에서 대체를 사용할 때 "c"와 유사합니다.

sed가 정말 이런 일을 하나요?

답변1

sed비대화형 플로우 에디터이기 때문에 사용이 불가능할 수도 있습니다. 이를 sed스크립트로 캡슐화하려면 너무 많은 생각이 필요합니다. 이렇게 하는 것이 더 쉽습니다 vim.

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

아래 설명에서 언급되었으므로 특정 파일 이름 와일드카드 패턴과 일치하는 현재 디렉터리의 여러 파일에 이를 사용하는 방법은 다음과 같습니다.

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

위의 두 셸 루프는 동일한 작업을 수행하는 명령을 갖도록 수정되었지만 find특정 디렉터리 안이나 아래에 top-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

다음을 수행하여 이를 얻을 수 있습니다.

:%s/OLD_TEXT/NEW_TEXT/gc

c구체적으로 세 번째 구분 기호 뒤에 추가하세요.

sed'c' 옵션은 Vim에서만 작동하며 명령줄에서는 사용할 수 없습니다 .

답변3

sed파일에 작업을 수행한 다음 결과를 임시 파일에 저장한 다음 대화형으로 원본 파일에 패치하는 데 사용할 수 있습니다 ( sdiff참조:http://www.gnu.org/software/diffutils/manual/diffutils.html#Invoking-sdiff):

sed -r 's/something/something_else/g' my_file > tmp_file
sdiff -o my_file -s -d my_file tmp_file

답변4

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경우 위의 내용 외에도 두 번째 "line by"로 바꿔야 합니다. 첫 번째 행"을 각 행에 대해 지정합니다.

관련 정보