산술 결과에 통합하려는 간단한 산술 방정식이 포함된 열이 있는 파일이 있습니다.
입력 샘플(탭으로 구분된 열):
+104-1+12 6 +3
각 열 내의 산술 합계를 계산하고 싶습니다. 열에 산술 기호가 포함되어 있지 않으면 +
항목 앞에 가 포함되어 있는 것처럼 처리합니다. +
열이 unsigned로 시작하는 경우 sed를 통해 기호를 추가하는 것이 쉬울 지라도 ( sed -E 's/(\t)([0-9]*)/\1\t+\2/g'
예제에서처럼 행이 숫자로 시작하지 않는다고 가정하면 작동 가능)
내 예상 결과는 다음과 같습니다.
115 6 3
유닉스에서 어떻게 이를 달성할 수 있나요? awk/sed 솔루션이 선호됩니다.
답변1
당신이 사용할 수있는 perl
:
perl -pe 's/[\d+-]+/eval$&/ge' your-file
심지어:
perl -pe 's/[\d+-]+/$&/gee' 파일 (Rakesh에게 감사드립니다)
zsh
같은
set -o extendedglob # for the ## operator (same as ERE +)
while IFS= read -r line; do
printf '%s\n' ${line//(#m)[0-9+-]##/$((MATCH))}
done < your-file
또는:
zmodload zsh/mapfile
set -o extendedglob
printf %s ${mapfile[your-file]//(#m)[0-9+-]##/$((MATCH))}
-
이 네 가지 중에서 우리는 숫자 와 문자 의 시퀀스를 찾고 +
이를 인터프리터의 산술 프로세서( eval
in perl
(또는 ee
대체 확장이 perl
코드로 평가되도록 하는 플래그), $((...))
in zsh
)에 전달합니다.
표현식을 인터프리터에 전달하기 전에 유효성을 검사하지 않으므로 오류가 발생할 수 있습니다(예: -+-
또는 같은 시퀀스 에서 3++
). 그러나 최소한 숫자와 -
/ +
문자만 고려하므로 보고된 오류보다 더 많은 오류가 발생하지는 않습니다. 메시지를 보내고 명령을 중단합니다.
답변2
반복하지 않겠습니다"sed" 추가대답; awk에서도 방법을 찾지 못했지만 여기에 bash 버전이 있습니다.
while IFS= read -r line
do
set -f; set -- $line
for e in "$@"
do
printf "%d " "$(( e ))"
done
echo
done < input
답변3
sed -E 's/(\t)([0-9])/\1+\2/g' data.file |
while IFS= read -r l; do
set -f; IFS=$'\t'
printf '0%s\n' $l | bc -l | paste -s -
done
sed -e 's/\t\([0-9]\)/\t+\1/' data.file |
while IFS= read -r l; do
set -f; IFS=$'\t'
printf '0%s\n' $l | bc -c |
sed -ne '
$!{
y/:@irKW/ /
s/[^ 0-9]/ & /g
s/[ ][ ]*/ /g;s/^[ ]*//;s/[ ]*$/p/p
}
' | dc | paste -s -
done
여기서는 수학적 표현의 표현을 생성 postfix
하고 이를 후위 계산기에 전달하기 전에 dc
명령 출력에서 수학적이 아닌 정보를 정리합니다 bc -c
.
결과
115 6 3
답변4
다음은 외부 실행 파일을 사용하지 않고 숫자의 문자열 표현을 숫자 표현으로 마샬링하는 awk의 기능을 활용하는 모든 awk 솔루션입니다.
awk -F"\t" \
'BEGIN { OFS="\t" }
{ gsub(/-/,"|-")
gsub(/\+/,"|")
for(i=1; i<=NF; i++) { ## iterate over columns
num_parts=split($i,parts,"|")
for(j=1; j<=num_parts; j++) ## iterate over arithmetic expression parts
sums[i] += parts[j]+0 ## Adding zero marshals the string into a numeric
}}
END{
for(i=1; i<=NF; i++) {
if(i>1) printf OFS
printf sums[i]
}
print "" }' file