거의 다 물어봤는데이미 같은 문제가 있습니다, 하지만 이번에는 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-8
if가 해당 문자를 반환하는데 이는 잘못된 것입니다.
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
cut
rev
다음은 ,(반전용) 및 셸 내장 명령을 사용하여 처음 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