Bashスクリプトを使用して2つのファイルを結合しようとしています。
ファイル1:
John (20)
Jim (30)
Adrian Lors (23)
ファイル2:
Jim
some jim info here
some jim other info
more jim info
John
some john info here
some john other info
more john info
Adrian Lors
some adrian info here
some adrian other info
more adrian info
予想される結果は次のようになりますが、試すことはできません。
ファイル3:
Jim (30)
some jim info here
some jim other info
more jim info
Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info
John (20)
some john info here
some john other info
more john info
理想的には、file3を括弧内の数字でソートしたいのですが、最大の問題は、2つのファイルを結合できないことです。シェルスクリプトでこれをどのように達成できますか?
ありがとう
答え1
これがあなたが探しているものかもしれません:
$ cat tst.awk
NR==FNR {
val = $NF
gsub(/^[[:space:]]+|[[:space:]]+[^[:space:]]+[[:space:]]*$/,"")
map[$0] = val;
next
}
FNR==1 {
FS = OFS = "\n"
ORS = "\n\n"
$0 = $0
}
{
$1 = $1 " " map[$1]
print
}
$ awk -f tst.awk file1 RS= file2
Jim (30)
some jim info here
some jim other info
more jim info
John (20)
some john info here
some john other info
more john info
Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info
答え2
join
、GNU、sed
および以下を使用してくださいsort
。
join -t '#'\
<(sed 's/ (/#(/' file1 | sort)\
<(sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort)\
| sort -t'#' -nrk2.2\
| sed '2,$ s/^/\n/g; s/#/ /; s/#/\n/g'
このコマンドでは、未使用の文字が一時フィールドの区切り文字#
と改行として使用されます。
出力:
Jim (30)
some jim info here
some jim other info
more jim info
Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info
John (20)
some john info here
some john other info
more john info
詳細
最初のパラメータjoin
$ sed 's/ (/#(/' file1 | sort
Adrian Lors#(23)
Jim#(30)
John#(20)
各行の最後の空白文字を結合区切り文字に置き換え、#
結果をソートします。
2番目のパラメータjoin
:
$ sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort
Adrian Lors#some adrian info here#some adrian other info#more adrian info
Jim#some jim info here#some jim other info#more jim info
John#some john info here#some john other info#more john info
sed -z
改行を簡単に置き換えるためにファイルを読み取るために使用されます。- 最初の2つの代替文字は、各名前のテキストを1行に配置するために使用されます。各改行文字を one に置き換え
#
、##
後ろの 2 つを 1 つの改行文字に置き換えます。 - 最後の代替文字
#
はファイルの末尾から削除されます(最後の改行文字)。 - 結果を並べ替えます。
接続して並べ替えた結果は次のとおりです。
$ join -t '#'\
<(sed 's/ (/#(/' file1 | sort)\
<(sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort)\
| sort -t'#' -nrk2.2
Jim#(30)#some jim info here#some jim other info#more jim info
Adrian Lors#(23)#some adrian info here#some adrian other info#more adrian info
John#(20)#some john info here#some john other info#more john info
最初のフィールドで 2 つの手続き型置換を連結し、2 番目のフィールドを位置 2 から始めて、逆の順序で数字でソートします。
残りの部分
... | sed '2,$ s/^/\n/g; s/#/ /; s/#/\n/g'
結合区切り文字を置き換えて改行文字を再インポートします。
- 行2(空白行)で始まる各行の先頭に改行文字を追加します。
- 各行の最初の行を
#
空白文字に置き換え、残りの#
'を改行文字に置き換えます。
答え3
働く:
理想的には、file3を括弧内の数字でソートしたいと思います。
努力する
$ sort -t\( -k2 file1 | awk '
FNR == NR {X = $1;
sub ($1 FS, "")
T[X] = $0
next
}
{X = $0
sub (/ [^ ]*$/, "", X)
}
X in T {print $0, T[X]
}
' RS= FS="\n" file2 RS="\n" ORS="\n\n" OFS="\n" -
John (20)
some john info here
some john other info
more john info
Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info
Jim (30)
some jim info here
some jim other info
more jim info
sort
必要に応じて、「括弧内の数字」でfile1をソートし、file2を読み取り、レコード区切り文字で空白行を使用して$ 1で索引付けされた配列に保存し、file1のソートされた結果を使用して索引ごとに配列を印刷します。