답변:
몇 가지 접근 방식이 있습니다. 내가 사용하고 중괄호 확장 ( file{1..4}.txt
) 수단을file1.txt file2.txt file3.txt file4.txt
펄
perl -i -pe 's/.*/ Good Morning / if $.==5' file{1..4}.txt
-i
: perl
원본 파일을 변경하고 제자리에서 파일을 편집합니다.
경우 -i
파일 확장자 접미사 다음에, 다음 백업은 수정 된 모든 파일에 대해 생성됩니다. 예는 : -i.bak
를 생성 file1.txt.bak
하는 경우 file1.txt
실행 중에 수정됩니다.
-p
: 입력 파일을 한 줄씩 읽고 스크립트를 적용하여 인쇄하는 것을 의미합니다.
-e
: 명령 행에서 스크립트를 전달할 수 있습니다.
s/.*/ Good Morning /
: 현재 줄 ( .*
) 의 텍스트 가 Good Morning으로 바뀝니다.
$.
입력 파일의 현재 행 번호를 보유하는 특수 Perl 변수입니다. 그래서 s/foo/bar/ if $.==5
, 수단 대신 foo
에 bar
단지 5 라인.
sed
sed -i '5s/.*/ Good Morning /' file{1..4}.txt
-i
: 에서처럼 perl
파일을 편집합니다.기본적으로 sed
입력 파일의 각 줄을 인쇄합니다. 5s/pattern/replacement/
5 라인 교체와 수단의 대체 패턴.
어 wk
for f in file{1..4}.txt; do
awk 'NR==5{$0=" Good Morning "}1;' "$f" > foobar && mv foobar "$f";
done
awk
-i
옵션 ¹에 해당하지 않습니다. 즉, 임시 파일 ( foobar
)을 만든 다음 원본을 덮어 쓰기 위해 이름을 바꿉니다 . bash 루프는 for f in file{1..4}.txt; do ... ; done
단순히 각 file{1..4}.txt
파일을 통과 하여 현재 파일 이름을로 저장합니다 $f
. 에서는 awk
, NR
현재 행 번호와 $0
현재 줄의 내용입니다. 따라서 스크립트는 $0
5 번째 줄에서만 줄 ( )을 "Good Morning"으로 바꿉니다. 1;
이다 awk
"선을 인쇄"를 참조하십시오.
¹ 새로운 버전은 devnull이 그의 답변 에서 보여준 것처럼 작동 합니다.
coreutils
for f in file{1..4}.txt; do
(head -4 "$f"; echo " Good Morning "; tail -n +6 "$f") > foobar &&
mv foobar "$f";
done
루프는 이전 섹션에서 설명되었습니다.
head -4
: 첫 4 행 인쇄
echo " Good Morning "
: "Good Morning"인쇄
tail -n +6
: 6 번째 줄부터 파일 끝까지 모든 것을 인쇄
이 ( )
세 명령 주위 의 괄호 를 사용하면 세 개의 출력 (첫 번째 4 행, "좋은 아침", 나머지 행)을 모두 캡처하여 파일로 리디렉션 할 수 있습니다.
당신은 사용할 수 있습니다 sed
:
sed '5s/^/Good morning /' file
Good morning
파일의 다섯 번째 줄에 추가 합니다.
대신 5 행의 내용을 바꾸려면 다음과 같이 말합니다.
sed '5s/.*/Good morning/' file
파일의 변경 사항을 제자리에 저장하려면 다음 -i
옵션을 사용하십시오 .
sed -i '5s/.*/Good morning/' file
sed
한 번에 둘 이상의 파일을 처리 할 수 있습니다. 명령 끝에 파일 이름을 더 추가 할 수 있습니다. bash 확장을 사용하여 특정 파일과 일치시킬 수도 있습니다.
# manually specified
sed -i '5s/.*/Good morning/' file1.txt file2.txt file3.txt file4.txt
# wildcard: all files on the desktop
sed -i '5s/.*/Good morning/' ~/Desktop/*
# brace expansion: file1.txt, file2.txt, file3.txt, file4.txt
sed -i '5s/.*/Good morning/' file{1..4}.txt
당신은 여기 중괄호 확장에 대한 자세한 내용을보실 수 있습니다 .
GNU awk 버전 4.1.0 이상 에는 내부 편집이 가능한 확장 기능 이 포함되어 있습니다. 그래서 당신은 말할 수 있습니다 :
gawk -i inplace 'NR==5{$0="Good morning"}7' file
파일의 5 번 라인을 Good morning
!
파이썬 솔루션을 보지 못했기 때문에 여기에 있습니다.
import sys
import os
def open_and_replace(filename):
with open(filename) as read_file:
temp = open("/tmp/temp.txt","w")
for index,line in enumerate(read_file,1):
if index == 5:
temp.write("NEW STRING\n")
else:
temp.write(line.strip() + "\n")
temp.close()
os.rename("/tmp/temp.txt",filename)
for file_name in sys.argv[1:]:
open_and_replace(file_name)
기본 아이디어는 명령 줄에 인수로 제공된 각 파일에 대해 임시 파일을 작성하고 각 파일을 원본 파일에 열거한다는 것입니다. 행의 인덱스가 5이면 다른 행을 써냅니다. 나머지는 오래된 파일을 임시 파일 데모로 바꾸는 것입니다.
$> ls
file1.txt file2.txt file3.txt
$> cat file1.txt
line 1
line 2
line 3
line 4
GOOD MORNING
line 6
$> python ~/replace_5th_line.py file1.txt file2.txt file3.txt
$> cat file1.txt
line 1
line 2
line 3
line 4
NEW STRING
line 6
$> cat file2.txt
line 1
line 2
line 3
line 4
NEW STRING
line 6
리스트 이해도 마찬가지입니다. 아래는 동일한 스크립트의 한 줄짜리입니다.
cat /etc/passwd | python -c 'import sys; print "\n".join(["CUSTOM" if index == 5 else line.strip() for index,line in enumerate(sys.stdin,1)])'
또는없이 cat
python -c 'import sys; print "\n".join(["CUSTOM" if index == 5 else line.strip() for index,line in enumerate(sys.stdin,1)])' < /etc/passwd
남은 것은 단순히 편집 된 내용의 출력을 다른 파일로 리디렉션하는 것입니다. > output.txt
다음은 이 답변에서 제안 된 펄 프로세스 를 마무리하는 bash 스크립트입니다
/ tmp / it
console:
enabled:false
그런 다음 다음을 실행하십시오.
$ search_and_replace_on_line_of_file.sh false true 2 /tmp/it
그리고 파일은 이제
/ tmp / it
console:
enabled:true
function show_help()
{
IT=$(CAT <<EOF
usage: SEARCH REPLACE LINE_NUM FILE
e.g.
false true 52 /tmp/it -> replaces false with true on line 52 of file /tmp/it
)
echo "$IT"
exit
}
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$4" ]
then
show_help
fi
SEARCH_FOR=$1
REPLACE_WITH=$2
LINE_NO=$3
FILE_NAME=$4
perl -i -pe "s/$SEARCH_FOR/$REPLACE_WITH/ if $.==$LINE_NO" $FILE_NAME