각 대체 전에 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 ... )
일을 하고 싶다
grep
이는 루프의 첫 번째 반복을 시작하기 전에 완료 되어야 합니다 . 즉,우아하지 않은, 그리고- 반환된 경로 이름은
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"로 바꿔야 합니다. 첫 번째 행"을 각 행에 대해 지정합니다.