일부 수식을 기반으로 각 행의 내용을 바꾸는 방법은 무엇입니까?

일부 수식을 기반으로 각 행의 내용을 바꾸는 방법은 무엇입니까?

나는 bash를 사용하여 일부 데이터를 여러 줄 파일로 출력하고 각 줄의 데이터를 다음 형식으로 저장했습니다.

text1 "text2" text3 integer1,integer2

"공백"은 각 행의 처음 4개 데이터 열을 구분합니다. 쉼표는 두 정수를 구분합니다. text2는 따옴표로 묶여 있습니다.

이제 bash를 사용하여 원본 데이터 파일의 각 줄을 평가한 다음 정수 1과 정수 2를 평가하기 위해 다른 수식을 사용하여 정수 1과 정수 2를 새 데이터로 바꾸고 싶습니다.

그런 다음 결과는 다음과 같이 새 파일(원본과 동일한 형식)로 출력되어야 합니다.

text1 "text2" text3 Newinteger1,Newinteger2

답변1

이 코드로 인해 여러분이 혼동하지 않았으면 좋겠습니다. #으로 시작하는 주석을 참조하세요.

테스트를 위해 다음 입력 파일을 사용합니다.

text1 "text2" text3 1,2
this "/usr/strange path with spaces/" works 2,3

다음 스크립트에 대한 입력은 다음과 같이 주어질 수 있습니다 cat input | while .... 셸은 스크립트의 마지막 줄이 완료된 후 cat발생하는 추가 프로세스를 방지하는 좋은 방법을 제공합니다. < input이제 기억해야 할 중요한 점은 두 번째 줄을 읽기 전에 한 줄을 구문 분석한다는 것입니다. 해당 행을 저장하는 변수를 호출하겠습니다 line. 이는 mybuf, firststring 또는 원하는 무엇이든 될 수 있습니다.
그럼 시작해 보겠습니다.

while read -r line; do
    # variable line is filled, just echo for debugging
    echo "The var line is filled with ${line}."
    # Special handling: you can cut off everything starting at the last space
    mystrings=${line% *}

    # You can also throw away everything up to a space.
    # Two # characters for throwing away the largest substring with "* "
    myints=${line##* }

    # Did it work? Two echoes just checking
    echo "mystring=${mystrings}"
    echo "myints=${myints}"

    # I'll try that strange thing with cutting up a variable again.
    # Now I want to cut the myint into two integers
    int1=${myints%,*}
    int2=${myints#*,}
    echo "My results are int1=${int1} and int2=${int2}"    
    # Some calculation.
    # The value of the vars can be used without the $ when used in (( ...))
    # Example new values: int1 will be given the original value of int2 + 5,
    # int2 will be doubled.
    # I did not add checks to see if int1 and int2 are integers
    (( int1 = int2 + 5 ))
    (( int2 = 2 * int2 ))
    # And show the result
    echo "${mystrings} ${int1},${int2}"
done < input

무슨 일이 일어나고 있는지 정확히 알고 싶을 때 시작 스크립트를 사용할 수 있습니다 set -x(디버깅을 켜고 다시 사용하여 끄십시오 set -).

답변2

awk로 가능한 솔루션


#!/usr/bin/awk -f
{ split($4, a, ","); printf("%s %s %s %d,%d\n", $1, $2, $3, a[1] / 2, a[2] + 500); }

분할 명령은 $4 열의 두 정수를 배열 a[]에 배치합니다. printf 명령은 표준 출력으로 인쇄합니다. 세 개의 자리 표시자 %s는 각각 세 개의 텍스트 열 $1, $2 및 $3에 해당합니다. 두 개의 %d 자리 표시자 폴더는 두 개의 정수입니다. 필요에 따라 두 정수 값의 계산을 변경합니다.

파일(예: awktest)에 저장하고 권한을 다음으로 설정합니다.

chmod +x ./awktest
실행해
./awktest <input.txt>output.txt

답변3

awk -F'[ ,]' '{$(NF-1)=$(NF-1)*6 "," $NF-10 ; NF=NF-1}1' multiline.file
  • -F'[ ,]',또는 <space>구분 기호로 설정
  • $NF— 마지막 필드
  • $(NF-1)— 마지막 필드는 변경된 마지막 필드와 마지막 필드 이전 필드로 구성됩니다.
  • $NF=$NF-1— 마지막 필드 삭제
  • 1— 결합된 줄을 인쇄합니다.

관련 정보