2つの文字区切り記号を使用して切り取り

2つの文字区切り記号を使用して切り取り

次のように、cut toと2つの文字区切り文字を使用して多くの行を持つファイルを処理したいと思います。

1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0

ただし、cutは単一文字のみを受け入れます。

代わりにcut -d'..'試してみますが、awk -F'..' "{echo $1}"うまくいきません。

私のスクリプト:

wget -O output.txt http://www.unicode.org/Public/emoji/6.0/emoji-data.txt                                                                             
sed -i '/^#/ d' output.txt                        # Remove comments                                                                                   
cat output.txt | cut -d' ' -f1 | while read line ;                                                                                                    
  do echo $line | awk -F'..' "{echo $1}"                                                                                                             
done  

答え1

awkフィールド区切り文字が2文字を超えるたびに正規表現として扱われます。..正規表現で任意の 2 文字を表します。エスケープするには、or withを.使用する必要があります。[.]\.

awk -F'[.][.]' ...
awk -F'\\.\\.' ...

(パラメータを取得または拡張するには、バックスラッシュ自体もエスケープする必要があります(少なくともgawkなどの一部のawkの場合)\n\b-F

あなたの場合:

awk -F' +|[.][.]' '/^[^#]/{print $1}' < output.txt

いずれにせよ、テキストを処理するシェルループの防止、気づくreadこのように使用しないでください、それecho任意のデータと一緒に使用しないでください。そして変数を引用することを忘れないでください

答え2

私に役立つサンプルテストスクリプトは次のとおりです。

#!/bin/sh

raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

for r in $raw
do
    f1=`echo "${r}" | cut -d'.' -f1`
    f2=`echo "${r}" | cut -d'.' -f2`
    f3=`echo "${r}" | cut -d'.' -f3`
    echo "field 1:[${f1}] field 2:[${f2}] field 3:[${f3}]"
done

exit

出力は次のとおりです

field 1:[1F3C6] field 2:[] field 3:[1F3CA]
field 1:[1F3CF] field 2:[] field 3:[1F3D3]
field 1:[1F3E0] field 2:[] field 3:[1F3F0]

編集する

Stéphane ChazelasのコメントとリンクされたQ&Aを読んだ後、上記の内容を書き換えて削除しましたloop

削除する方法が見つかりません。loop そしてこれらの部分を渡すことができる変数のままにしてください(例:;$f1$f2私の元の答え)。$f3元の質問から出力が何であるかはまだわかりません。

まず、次の操作を続けてくださいcut

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | cut -d'.' -f1,3

すると、以下が出力されます。

1F3C6.1F3CA
1F3CF.1F3D3
1F3E0.1F3F0

.--output-delimiter=STRING表示された文字列はで置き換えることができます。

次に、出力をより効果的に制御するには、sed代わりにwithを使用します。cut

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | sed 's/^\(.*\)\.\.\(.*\)$/field 1 [\1] field 2 [\2]/'

これにより、次のものがレンダリングされます。

field 1 [1F3C6] field 2 [1F3CA]
field 1 [1F3CF] field 2 [1F3D3]
field 1 [1F3E0] field 2 [1F3F0]

答え3

IFS を使用して各行を分割し、2 つのポイント間のフィールドを削除できます。

#/bin/sh
while IFS=\. read a _ b
do
     echo "field one=[$a] field two=[$b]"
done < "file"

実装する:

$ ./script
field one=1F3C6 field two=1F3CA
field one=1F3CF field two=1F3D3
field one=1F3E0 field two=1F3F0

ファイルが次のようになっているとしましょう。

$ cat file
1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0

答え4

私が作ったパッチフィールドモードで動作し、複数の連続した区切り文字を単一の区切り文字として扱う新しい-mコマンドラインオプションが追加されました。cutこれは基本的にOPの問題をかなり効率的な方法で解決します。また、このパッチがcoreutilsプロジェクトにマージされることを望み、数日前にこのパッチのアップストリームを送信しました。

いくつかありますもっと考えるスペース関連の機能を追加することについてのフィードバックを持ち、cutこれらすべてにフィードバックを提供することをお勧めします。より多くのパッチを実装し、cutそれをアップストリームに送信してユーティリティをより多様にし、さまざまな実際のシナリオで利用できるようにしたいと思います。

関連情報