[bash] 텍스트 파일의 전체 줄을 줄 번호로 바꾸는 방법

bash 스크립트가 파일의 전체 줄을 바꾸려는 상황이 있습니다. 줄 번호는 항상 동일하므로 하드 코딩 된 변수가 될 수 있습니다.

해당 줄의 일부 하위 문자열을 바꾸려고하지 않고 해당 줄을 완전히 새 줄로 바꿉니다.

이 작업을 수행하는 bash 메서드가 있습니까 (또는 .sh 스크립트에 던져 질 수있는 간단한 방법).



답변

가장 크지는 않지만 작동해야합니다.

sed -i 'Ns/.*/replacement-line/' file.txt

여기서 N대상 행 번호로 대체해야합니다. 원본 파일의 줄이 바뀝니다. 변경된 텍스트를 다른 파일에 저장하려면 -i옵션을 삭제하십시오 .

sed 'Ns/.*/replacement-line/' file.txt > new_file.txt


답변

실제로이 스크립트를 사용하여 회사 UNIX 서버의 cron 파일에있는 코드 줄을 한 번에 바꿨습니다. 우리는 일반적인 쉘 스크립트로 실행했으며 아무런 문제가 없었습니다.

#Create temporary file with new line in place
cat /dir/file | sed -e "s/the_original_line/the_new_line/" > /dir/temp_file
#Copy the new file over the original file
mv /dir/temp_file /dir/file

이것은 행 번호를 기준으로하지 않지만 행 번호 앞에 s/와 번호를 배치하여 행 번호 기반 시스템으로 쉽게 전환 할 수 있습니다 the_original_line.


답변

4 행을 “different”라는 텍스트로 바꾸고 싶다고 가정 해 봅시다. 다음과 같이 AWK를 사용할 수 있습니다.

awk '{ if (NR == 4) print "different"; else print $0}' input_file.txt > output_file.txt

AWK는 입력을 “필드”로 나눈 “레코드”로 간주합니다. 기본적으로 한 줄은 하나의 레코드입니다. NR본 레코드 수입니다. $0는 현재 완료 레코드를 나타냅니다 (레코드 $1의 첫 번째 필드 등). 기본적으로 필드는 줄의 단어입니다.

따라서 현재 행 번호가 4 인 경우 문자열 “different”를 인쇄하지만 변경되지 않은 행을 인쇄하십시오.

AWK에서, 포함 된 프로그램 코드 { }는 각 입력 레코드 에서 한 번 실행됩니다.

쉘이와 같은 것을 해석하지 못하게하려면 AWK 프로그램을 작은 따옴표로 인용해야합니다 $0.

편집 : 아래 의견에서 @chepner의 짧고 우아한 AWK 프로그램 :

awk 'NR==4 {$0="different"} { print }' input_file.txt

레코드 (예 : 행) 번호 4에 대해서만 전체 레코드를 “different”문자열로 바꾸십시오. 그런 다음 모든 입력 레코드에 대해 레코드를 인쇄하십시오.

분명히 내 AWK 기술은 녹슨 것입니다! 감사합니다, @chepner.

편집 : @Dennis Williamson의 더 짧은 버전도 참조하십시오.

awk 'NR==4 {$0="different"} 1' input_file.txt

이것이 작동하는 방식은 주석에 설명되어 있습니다. 1always는 true로 평가되므로 관련 코드 블록이 항상 실행됩니다. 그러나 관련 코드 블록이 없으므로 AWK가 전체 행을 인쇄하는 기본 작업을 수행합니다. AWK는 이와 같은 간결한 프로그램을 허용하도록 설계되었습니다.


답변

이 테스트 파일 (test.txt)이 주어지면

Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Duis eu diam non tortor laoreet
bibendum vitae et tellus.

다음 명령은 첫 줄을 “줄 바꾸기 텍스트”로 바꿉니다.

$ sed '1 c\
> newline text' test.txt

결과:

newline text
consectetur adipiscing elit.
Duis eu diam non tortor laoreet
bibendum vitae et tellus.

자세한 내용은 여기를 참조하십시오

http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/


답변

bash에서 N, M을 줄 번호로 바꾸고 xxx yyy를 원하는 것으로 바꿉니다.

i=1
while read line;do
  if((i==N));then
    echo 'xxx'
  elif((i==M));then
    echo 'yyy'
  else
    echo "$line"
  fi
  ((i++))
done  < orig-file > new-file

편집하다

실제로이 솔루션에는 문자 “\ 0” “\ t”및 “\”에 문제가 있습니다.

“\ t”, 읽기 전에 IFS =를 넣어서 해결할 수 있습니다 : “\”, -r

IFS= read -r line

그러나 “\ 0″의 경우 변수가 잘립니다. 순수한 bash에는 해결책이 없습니다. Bash의 변수에 널 문자 (\ 0)를 포함하는 문자열을 지정하십시오 .

그러나 일반 텍스트 파일에는 널 문자 \ 0 이 없습니다.

펄은 더 나은 선택이 될 것입니다

perl -ne 'if($.==N){print"xxx\n"}elsif($.==M){print"yyy\n"}else{print}' < orig-file > new-file


답변

# Replace the line of the given line number with the given replacement in the given file.
function replace-line-in-file() {
    local file="$1"
    local line_num="$2"
    local replacement="$3"

    # Escape backslash, forward slash and ampersand for use as a sed replacement.
    replacement_escaped=$( echo "$replacement" | sed -e 's/[\/&]/\\&/g' )

    sed -i "${line_num}s/.*/$replacement_escaped/" "$file"
}


답변

Chepner의 훌륭한 답변. bash Shell에서 나를 위해 일하고 있습니다.

 # To update/replace the new line string value with the exiting line of the file
 MyFile=/tmp/ps_checkdb.flag

 `sed -i "${index}s/.*/${newLine}/" $MyFile`

here-
index줄 번호 없음
newLine-바꿀 새 줄 문자열입니다.

마찬가지로 아래 코드는 파일에서 특정 줄을 읽는 데 사용됩니다. 실제 파일에는 영향을 미치지 않습니다.

LineString=`sed "$index!d" $MyFile` 

here
!d-line no 이외의 행을 삭제 합니다. 따라서 파일에서 $index
출력을 no의 문자열로 가져옵니다 $index.