첫 번째와 다섯 번째 열을 얻기 위해 다음 데이터를 처리 중입니다. 형식을 형식 D
으로 변환 E
하고 횡설수설이 포함된 행을 제거합니다 9.410-316
.
DEG = 1.500
2.600D+01 0.000D+00 0.000D+00 0.000D+00 0.000D+00
2.700D+01 8.720-304 2.369-316 7.556-316 9.410-316
4.300D+01 1.208D-83 4.156D-96 7.360D-96 6.984D-96
1.590D+02 8.002D-07 6.555D-19 7.748D-19 7.376D-19
1.600D+02 1.173D-06 9.669D-19 1.143D-18 1.089D-18
1.610D+02 1.709D-06 1.417D-18 1.676D-18 1.596D+01
1.620D+02 2.468D-06 2.058D-18 2.436D-18 2.320D-10
DEG = 18.500
2.700D+01 2.794-314 0.000D+00 0.000D+00 0.000D+00
2.800D+01 4.352-285 1.224-297 3.685-297 4.412-297
8.800D+01 1.371D-02 6.564D-15 7.852D-15 7.275D-15
내 문제는 제거할 숫자 형식을 결정하는 것입니다. 지금까지 나는 시도했다
maxa=18.5
maxangle=$(printf "%.3f" $maxa)
if (( $(echo "$maxa < 10" | bc -l) )); then
txt2search="DEG = $maxangle"
# 6 spaces between = and value if deg=>10, else only 5)
else
txt2search="DEG = $maxangle"
fi
line=$(grep -n "$txt2search" file | cut -d : -f 1)
# Once the line number is read for the string, skip a few lines (4) and read next several lines(1000)
beginline=$((line + 4))
endline=$((line + 1002))
awk -v a="$beginline" -v b="$endline" 'NR==a, NR==b {print $1, $5}' fileinput > fileoutput
sed -i 's/D/E/g' fileoutput
그런 다음 의미 없는 숫자가 있는 행을 삭제하기 위해 한 번에 하나씩 시도했지만 다음 명령으로 실패했습니다.
sed -ni '/E/p' fileoutput
sed -E '/(E)/!d' fileoutput > spec2.tempdata
sed '/E/!d' fileoutput > spec2.tempdata
awk '!/E/' fileoutput > spec2.tempdata
이렇게 의미 없는 숫자가 포함된 행을 어떻게 식별하고 삭제할 수 있나요? 버전은
- sed (GNU sed) 4.7
- grep (GNU grep) 3.4
- GNU Awk 5.0.1, API: 2.0(GNU MPFR 4.0.2, GNU MP 6.2.0)
출력은 다음과 같습니다
2.600D+01 0.000D+00 0.000D+00 0.000D+00 0.000D+00
4.300D+01 1.208D-83 4.156D-96 7.360D-96 6.984D-96
1.590D+02 8.002D-07 6.555D-19 7.748D-19 7.376D-19
1.600D+02 1.173D-06 9.669D-19 1.143D-18 1.089D-18
1.610D+02 1.709D-06 1.417D-18 1.676D-18 1.596D+01
1.620D+02 2.468D-06 2.058D-18 2.436D-18 2.320D-10
편집하다:내가 찾고있는 해결책은 (첫 번째 댓글 참조)
grep -v '[0-9]-'
답변1
사용행복하다(이전 Perl_6)
~$ raku -e 'my @a; for lines.join("\n").split(/ \n <?before DEG> /) { @a.push: %(.split("\n").[0].words.[2] => \
.split("\n")[1..*].map(*.words[0,4])>>.map(*.subst( / (\d+) (<[+-]>) /, {$0 ~ "e" ~ $1} ).subst(/D/, "e") )>>.Num) }; \
.raku.put for @a;' file
시각화 목적의 출력 예:
${"1.500" => $($(26e0, 0e0), $(27e0, 9.41e-316), $(43e0, 6.984e-96), $(159e0, 7.376e-19), $(160e0, 1.089e-18), $(161e0, 15.96e0), $(162e0, 2.32e-10))}
${"18.500" => $($(27e0, 0e0), $(28e0, 4.412e-297), $(88e0, 7.275e-15))}
Raku는 유리수와 내장된 유니코드 지원 기능을 갖춘 Perl 제품군의 프로그래밍 언어입니다. 위에서 일반적인 전략은 1열과 5열(인덱스)의 값이 DEG
측정된 값의 합이 되는 해시 배열을 만드는 것입니다.key
[0,4]
value
@
- 서명된 array()가 선언되었습니다 @a
. Raku 코드는 자동으로 이를 읽고 lines
개행 join
문자에 다시 합칩니다 \n
. 여기서부터 이전에 발생한 개행 문자를 split
찾아 기록을 깨뜨립니다 . 블록 을 입력하면 각 레코드가 다시 래핑 되고 첫 번째 요소의 세 번째 단어는 가 됩니다 . 두꺼운 화살표는 가 되는 "쌍" 구조를 나타냅니다 . 이 두 호출에 유의하세요. 숫자 뒤의 첫 번째 호출과 더하기 기호를 사용하거나 삽입합니다 . 빼기 기호로 구성된 사용자 정의 문자 클래스 사이에 "e"가 있고 두 번째 호출은 "D"를 "e"로 변경합니다. 값이 변환되고 해시 값이 배열로 푸시됩니다. 이 메서드는 Raku 데이터의 내부 표현을 시각화할 수 있도록 출력 행에 추가됩니다(노트는 동의어로 사용될 수도 있음).\n
DEG
{ … }
split
\n
.[0].words.[2]
key
=>
value
.subst
\d
<[+-]>
.Num
%( … )
@a
.raku
.perl
플롯의 실제 출력:
.raku.put for @a
원하는 플롯 출력을 얻으려면 마지막 줄을 변경하십시오 . 다음은 몇 가지 예입니다(필요한 경우 Raku printf
또는 Raku를 사용할 수도 있습니다 sprintf
).
1.put
첫 번째 줄을 반환하려면 위의 out 줄을 바꾸세요 DEG
.
for @a[0].kv -> $k,$v {put ([Z] $k xx $v.elems, $v).join: "\n"}
#Returns 3-columns:
1.500 26 0
1.500 27 9.41e-316
1.500 43 6.984e-96
1.500 159 7.376e-19
1.500 160 1.089e-18
1.500 161 15.96
1.500 162 2.32e-10
2.또는 다음 줄을 사용하여 전체 3개 목록을 한 번에 반환합니다 put
.
for @a { for ($_.kv) -> $k,$v {put ([Z] $k xx $v.elems, $v).join: "\n"}};
#Returns:
1.500 26 0
1.500 27 9.41e-316
1.500 43 6.984e-96
1.500 159 7.376e-19
1.500 160 1.089e-18
1.500 161 15.96
1.500 162 2.32e-10
18.500 27 0
18.500 28 4.412e-297
18.500 88 7.275e-15
삼. 마침내: Raku에는 =~=
값이 대략적인지 여부를 결정하는 데 사용할 수 있는 "공차" 연산자가 있습니다. 0과 같습니다(기본값은 1e-15, 아래 링크 참조). 함께 넣어보세요:
~$ raku -e 'my @a; for lines.join("\n").split(/ \n <?before DEG> /) { @a.push: %(.split("\n").[0].words.[2] => \
.split("\n")[1..*].map(*.words[0,4])>>.map(*.subst( / (\d+) (<[+-]>) /, {$0 ~ "e" ~ $1} ).subst(/D/, "e") )>>.Num) }; \
for @a { for ($_.kv) -> $k,$v {put ([Z] $k xx $v.elems, $v>>.map( -> $i { ($i =~= 0) ?? 0 !! $i } )).join: "\n"}};' file
1.500 26 0
1.500 27 0
1.500 43 0
1.500 159 0
1.500 160 0
1.500 161 15.96
1.500 162 2.32e-10
18.500 27 0
18.500 28 0
18.500 88 7.275e-15
https://docs.raku.org/언어/hashmap.html
https://docs.raku.org/언어/5to6-nutshell.html#=%3E_Fat_comma
https://docs.raku.org/routine/=~=.html
https://raku.org
답변2
FWIW는 입력의 D를 E로 변경한 다음 필드를 추가하기 전과 후의 값을 비교하여 필드가 숫자인지 확인하는 방법입니다 0
(숫자는 값을 유지하고 숫자가 아닌 값은 유지하지 않음).
$ awk 'NF>3{gsub(/D/,"E"); for (i=1; i<=NF; i++) if ($i != $i+0) print "not a number:", $i}' file
not a number: 8.720-304
not a number: 2.369-316
not a number: 7.556-316
not a number: 9.410-316
not a number: 2.794-314
not a number: 4.352-285
not a number: 1.224-297
not a number: 3.685-297
not a number: 4.412-297
따라서 숫자만 포함하는 줄을 인쇄하면 다음과 같습니다.
$ awk 'NF>3{gsub(/D/,"E"); for (i=1; i<=NF; i++) if ($i != $i+0) next; print}' file
2.600E+01 0.000E+00 0.000E+00 0.000E+00 0.000E+00
4.300E+01 1.208E-83 4.156E-96 7.360E-96 6.984E-96
1.590E+02 8.002E-07 6.555E-19 7.748E-19 7.376E-19
1.600E+02 1.173E-06 9.669E-19 1.143E-18 1.089E-18
1.610E+02 1.709E-06 1.417E-18 1.676E-18 1.596E+01
1.620E+02 2.468E-06 2.058E-18 2.436E-18 2.320E-10
8.800E+01 1.371E-02 6.564E-15 7.852E-15 7.275E-15
또는:
$ awk 'NF>3{gsub(/D/,"E"); for (i=1; i<=NF; i++) if ($i != $i+0) next} 1' file
DEG = 1.500
2.600E+01 0.000E+00 0.000E+00 0.000E+00 0.000E+00
4.300E+01 1.208E-83 4.156E-96 7.360E-96 6.984E-96
1.590E+02 8.002E-07 6.555E-19 7.748E-19 7.376E-19
1.600E+02 1.173E-06 9.669E-19 1.143E-18 1.089E-18
1.610E+02 1.709E-06 1.417E-18 1.676E-18 1.596E+01
1.620E+02 2.468E-06 2.058E-18 2.436E-18 2.320E-10
DEG = 18.500
8.800E+01 1.371E-02 6.564E-15 7.852E-15 7.275E-15
DEG
이 라인을 출력 할지 여부에 따라 다릅니다 .