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(最後に使用された)最後の2つの列を取得するコマンドは何ですか?これにより、次のような結果が得られます。

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

ご覧のとおり、2行目には追加の;文字があるため、ここではこのようなコマンドを使用できません。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

もちろん、これらの文は1行に配置することもできます。

編集する:

私はいくつかの1行の代替案を収集しましたrev(最終コンテンツの印刷を省略)。'\N'):

Python: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

関連情報