cut 명령을 사용하여 행의 첫 번째 요소와 마지막 요소를 얻는 방법은 무엇입니까?

cut 명령을 사용하여 행의 첫 번째 요소와 마지막 요소를 얻는 방법은 무엇입니까?

거의 다 물어봤는데이미 같은 문제가 있습니다, 하지만 이번에는 X를 검색하고 싶습니다.최신CSV 파일의 요소 행입니다. 예를 들어 입력 파일은 다음과 같습니다.

1;foo;bar;baz;x;y;z
2;foo;bar;baz;x;y;z
3;foo;bar;baz;x;y;z

cut(최종적으로 사용된) 마지막 두 열을 가져오는 명령은 무엇입니까? 그러면 다음과 같은 결과를 얻습니다.

y;z
y;z
y;z

사실, 나의 진짜 목표는 처음 3개를 검색하는 것입니다.그리고각 행의 마지막 2개 필드는 다음과 같습니다.

1;foo;bar;y;z
2;foo;bar;y;z
3;foo;bar;y;z

cut -d \; -f 1-3,10-11불행히도 CSV 파일이 따르지 않기 때문에 비슷한 명령을 사용할 수 없습니다 (행에 11개의 요소가 있는 경우).진짜CSV 형식. 실제로 행 중앙에 있는 일부 필드는 다음과 같습니다.암호화됨, 암호화된 값에는 때때로 ;문자가 포함될 수 있습니다(물론 내부에 포함되지는 않습니다 "). 즉, 내 라인은 다음과 같습니다.

1;foo;bar;#@$"é&^l#;baz;x;y;z
2;foo;bar;#¤=é;)o'#;baz;x;y;z
3;foo;bar;#]]'~é{{#;baz;x;y;z

보시다시피, 두 번째 줄에는 추가 ;문자가 있으므로 여기서는 이와 같은 명령을 사용할 수 없습니다. cut -d \; -f 1-3,7-8if가 해당 문자를 반환하는데 이는 잘못된 것입니다.

1;foo;bar;y;z
2;foo;bar;x;y  (-> Wrong here, there is a shift)
3;foo;bar;y;z

그러면 어떻게 이를 사용하여 cut문제를 해결할 수 있습니까?

감사해요

ps: 저는 특히 이 cut명령을 좋아합니다. 따라서 제가 원하는 것을 수행하는 명령이 있지만 그렇지 않은 경우 cut에도 괜찮습니다. :)

편집하다이 기계는 꽤 오래되었다는 점은 주목할 가치가 있습니다: uname -a다음 메시지를 제공합니다:

SunOS ###### 5.10 Generic_142900-05 sun4u sparc SUNW,Sun-Fire-V240

일부 명령은 존재하지 않을 수 있습니다(예 rev: ).

답변1

귀하의 버전에서는 SunOS nawk(또는 그 문제에 대해 awk) 다음을 수행하는 것이 가능해야 합니다.

 nawk -F';' 'BEGIN{OFS=";"}{print($1,$2,$3,$(NF-1),$(NF))}' file.txt 

답변2

cutrev다음은 ,(반전용) 및 셸 내장 명령을 사용하여 처음 3개와 마지막 2개 필드를 검색하기 위한 다중 명령 솔루션입니다 .

while read line
do
    first=$(echo -n "$line" | cut -d ";" -f -3)
    second=$(echo -n "$line" | rev | cut -d ";" -f -2 | rev)
    echo "$first;$second"
done < my_file

물론, 이러한 명령문은 한 줄에 배치될 수도 있습니다.

편집하다:

나는 몇 가지 한 줄 대안을 수집했습니다 rev(최종 내용 인쇄 생략).'\N'):

파이썬:python -c "import sys; sys.stdout.write(raw_input()[::-1])

진주:perl -ne 'chomp;print scalar reverse;'

더 많은 가능성이 있습니다문자열 반전. 아마도 이들 중 일부는 귀하의 시스템에서 작동할 것입니다.

답변3

% cat a
1;foo;bar;#@$"é&^l#;baz;x;y;z
2;foo;bar;#¤=é;)o'#;baz;x;y;z
3;foo;bar;#]]'~é{{#;baz;x;y;z
% sed -r 's,^(([^;]+;){3}).*;([^;]+;[^;]+)$,\1\3,' < a
1;foo;bar;y;z
2;foo;bar;y;z
3;foo;bar;y;z

답변4

저는 개인적으로 awk 또는 perl 접근 방식을 사용하지만 많은 추가 프로세스 없이 Solaris 10(지금은 보관해 두었습니다)의 bash 3.2에 내장된 명령을 통해 수행할 수도 있습니다.

# unless in a one-off script, save IFS first and restore afterwards
# most simply just put this in parens so it runs in a subshell
IFS=';'; while read -ra a;do N=${#a[*]}; 
  set -- "${a[0]}" "${a[1]}" "${a[2]}" "${a[N-2]}" "${a[N-1]}";
  printf %s\\n "${*}";done  <in >out

관련 정보