나는 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
— 결합된 줄을 인쇄합니다.