빼기 기호를 유지한 채 특정 열의 숫자 값을 삭제하시겠습니까?

빼기 기호를 유지한 채 특정 열의 숫자 값을 삭제하시겠습니까?

홀수 열에만 음수를 사용하여 수평 및 수직으로 무한히 계속되는 다음 데이터 프레임이 있습니다.

-1  2  3  4 -5  9
 2  3 -4  5 -6  11

나는 두 번째, 네 번째, 여섯 번째 전체 열(또는 모든 짝수 열)을 원하고 마이너스 기호는 첫 번째, 세 번째, 다섯 번째(또는 모든 홀수 열)에서만 원하므로 다음과 같은 결과를 얻습니다.

- 2   4 - 9
  3 - 5 - 11

마침내 다음과 같은 결과를 얻었습니다.

-2  4 -9
 3 -5 -11

따라서 동일하게 유지하려면 짝수 열의 값이 필요하고 홀수 열의 값은 음수 값이 있으면 그대로 유지하고 양수 값이 있으면 폐기합니다.

awk/sed를 사용하여 이를 수행할 수 있는 방법이 있습니까?

제가 아는 한 대략 이렇습니다.

awk '{ for (i=2;i<=NF;i+=2) $i="" }1' FILE.txt | sed 's/[0-9,.]*//g' 

답변1

방법 sed:

sed -E '
    s/^(([ \t]*-?[ \t]*[0-9.]+[ \t]+[0-9.]+)*)[ \t]+-?[ \t]*[0-9.]+$/\1/;
    s/[0-9.]+[ \t]+([0-9.]+)/\1/g'

산출:

-2  4 -9
 3 -5 -11

열 수가 홀수인 경우 첫 번째 표현식은 후행 열을 제거합니다. <number> <number>첫 번째 숫자가 음수일 수 있는 0개 이상의 쌍을 찾아서 이를 수행합니다 .

편집하다:sed@mikeserv에서 영감을 받은 더 짧은 솔루션:

sed -E '
    s/[0-9.]+[ \t]*([0-9.]*)/\1/g;
    s/[- \t]*$//'

똑같은 것 perl:

perl -lpe 's/^((\s*-?\s*[\d.]+\s*[\d.]+)*)\s+-?\s*[\d.]+$/$1/o; s/[\d.]+\s+([\d.]+)/$1/g'

다른 방법 perl(아마도 가장 깨끗한 방법):

perl -lpe '$a = 1; s/([\d.]+\s*)/$a++ % 2 ? "" : $1/eg; s/[-\s]*$//o'

답변2

하나씩 perl:

$ perl -anle 'BEGIN{$,=" "}
  print map{$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"}grep{!($_%2)}0..$#F' file
-2  4 -9
 3 -5 -11
  • -an@F입력을 배열 로 분할
  • BEGIN{$,=" "}출력 필드 구분 기호를 공백으로 설정
  • grep{!($_%2)}0..$#F배열의 모든 짝수 인덱스를 가져옵니다 @F. 즉, 홀수 요소의 인덱스를 가져옵니다.
  • map{$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"}홀수 요소가 시작하는지 확인한 -후 다음 짝수 요소에 추가하고 -그렇지 않으면 공백을 추가합니다.

답변3

@terdon 님처럼답변하지만 sed가 없으면:

awk '{ for(i=1;i<=NF;i+=2){
         if ($i<0) $(i+1)*=-1;
         $i = "";
       }
       print
     }'

답변4

한 가지 방법은 다음과 같습니다.

$ awk '{for(i=1;i<=NF;i+=2){if($i<0){$i="-"}else{$i="";} }};1' file |
     sed 's/- */-/g; s/  */ /g'
-2 4 -9
 3 -5 -11

스크립트 awk는 모든 홀수 열을 반복하여 -해당 값이 음수이면 값을 설정하고, 그렇지 않으면 null로 설정합니다. 그런 다음 seda 뒤의 모든 공백을 제거 -하고 여러 개의 연속 공백을 단일 공백으로 바꿉니다. 이는 일부 필드에 두 개 이상의 문자가 포함되고 다른 필드에는 하나의 문자가 포함되므로 정렬이 깨짐을 의미합니다. 문제가 되지 않는 필드를 사용했다면 보기에 좋지 않을 뿐입니다.

관련 정보