파일의 인덱스 증가

파일의 인덱스 증가

알겠습니다. 필요한 작업을 수행할 수 있는 방법을 찾을 수 없는 것 같습니다.

다음과 같은 텍스트 파일 A가 있다고 가정해 보겠습니다.

(freqBiasL2[27])      
(SatBiasL1[27])       
(defSatBiasL2_L1[27]) 
(defSatBiasSlope[27]) 
(defSatBiasSigma[27]) 

(freqBiasL2[28])      
(SatBiasL1[28])       
(defSatBiasL2_L1[28]) 
(defSatBiasSlope[28]) 
(defSatBiasSigma[28]) 

(freqBiasL2[29])      
(SatBiasL1[29])       
(defSatBiasL2_L1[29]) 
(defSatBiasSlope[29]) 
(defSatBiasSigma[29])

등등. 각 인덱스 i = i+3이 되도록 [] 대괄호 사이의 인덱스를 변경하고 싶습니다.

for 루프와 sed를 조합하여 시도했지만 작동하지 않습니다.

for i in {27..107..1}
do
    i_new=$((i+3))
    sed -e 's/\['$i'\]/\['$i_new'\]/' prova.txt 

done

문제는 처음 27을 30으로 변경하지만 다음 번에는 인덱스가 30인 블록 2개(변경된 블록과 원본 블록)를 찾게 된다는 것입니다.

이미 변경된 인덱스를 덮어쓰지 않고 어떻게 할 수 있나요?

좋습니다. 개선을 위해 질문을 편집합니다. 다음과 같은 인덱스가 2개 있는 경우 비슷한 작업을 수행하려면 어떻게 해야 합니까?

(freqBiasL2[32][100])
(SatBiasL1[32][101])
(defSatBiasL2_L1[32][102])
(defSatBiasSlope[32][103])
(defSatBiasSigma[32][104])

첫 번째 인덱스를 무시하고 두 번째 인덱스만 증가시키고 싶나요?

답변1

펄을 사용하세요:

perl -pe 's/(?<=\[)(\d+)(?=\])/$1+1/ge' prova.txt

설명:

  • -p모든 줄을 반복하고 모든 줄 후에 결과를 인쇄하는 것을 의미합니다.
  • -e모든 줄에서 실행할 표현식을 정의합니다.
  • s/from/to/간단한 대체를 수행합니다
  • s/(\d+)/$1+1/ge하나 이상의 숫자와 일치하고 이를 로 캡처 $1한 다음 e끝에 있는 수정자는 대체 문자열이 표현식임을 Perl에게 알려줍니다. 더하기 1 $1+1의 값을 대체합니다 . 수정자는 이 대체를 전역적으로, 즉 한 줄에 두 번 이상 수행하는 것을 의미합니다.$1g
  • (?<=\[)길이가 0인 긍정적인 LookBehind 어설션입니다. 이는 그 뒤에 오는 것이 앞에 있는 경우에만 일치한다는 것을 의미합니다 ( 정규식의 특수 토큰과 마찬가지로 [이스케이프해야 함 ). 길이가 0이라는 것은 대체될 ​​항목의 일부가 아니라는 것을 의미합니다.\[
  • (?=\])길이가 0인 긍정적인 예측 어설션입니다. 이는 그 앞에 오는 것이 뒤에 오는 경우에만 일치한다는 것을 의미합니다 ](다시 이스케이프됨).

따라서 이것은 그 숫자 사이의 모든 숫자를 취하고 그 숫자를 증가 [시킵니다 ].

답변2

다음을 사용할 수도 있습니다 awk.

awk -F '[\\[\\]]' '{if ($2) { sub($2, $2 + 3)}} 1' prova.txt

실제로 이는 다음과 같이 약간 단축될 수 있습니다.

awk -F '[\\[\\]]' '$2 { sub($2, $2 + 3)} 1' prova.txt

답변3

나는 당신이 이미 문제를 해결했다는 것을 알고 있지만 참고로 당신은 코드를 매우 간단하게 수정하여 문제를 해결할 수 있었습니다. 즉, 루프를 반복하는 시퀀스를 반전시키는 것입니다.

30을 교체하면 원래의 30만 발견되고 27은 아직 교체되지 않았기 때문에 를 사용하면 {107..27..-1}(또는 더 간결하게 ) 문제를 해결하기에 충분할 것입니다.{107..27}

답변4

좋아, 이중 인덱스에 대한 솔루션과 cas 명령을 수정한 솔루션이 있다고 생각합니다. 이렇게 하면 작업이 수행됩니다.

perl -p -e 's/\[(\d+)\]\[(\d+)\]/"[" . ($1) . "][" . ($2+40) . "]"/ge' prova.txt

그런데 왜 . ($1) .(공백이 있는 지점)이 필요한지 잘 모르겠습니다.

관련 정보