2つの変数を使用して単一のテキストファイルを構成します。

2つの変数を使用して単一のテキストファイルを構成します。

次の内容でテキストファイルを作成しようとしています。

user name is ${name}
and his mobile number is ${number}

ユーザーが10人で携帯電話番号が10個あります。ユーザー名はに保存され、user.txt連絡先番号はに保存されますcontact.txt

user.txt次のようになります。

apple
cat
tom

contact.txt次のように、

1234
3456
5678

私の出力は次のとおりです。

user name is apple
and his mobile number is 1234

user name is cat
and his mobile number is 3456

user name is tom
and his mobile number is 5678

この出力を単一のファイルにしたい。誰かがシェルとPythonスクリプトを助けることができますか?

答え1

これは、標準シェルの組み込みおよび一般的なツールを使用して行うことができます。

paste -d'|' user.txt contact.txt | while IFS='|' read user contact ; do
  printf "user name is %s\nand their mobile is %s\n" "${user}" "${contact}"
done

入力リダイレクトにしばしば好まれるbashismを使ったわずかなリミックスです。

while IFS='|' read user contact ; do
  printf "user name is %s\nand their mobile is %s\n" "${user}" "${contact}"
done < <(paste -d"|" user.txt contact.txt)

> "somefilename.txt"コマンドの最後の行に追加すると、出力全体を選択したファイルにリダイレクトできます。

答え2

このpasteコマンドを使用すると、2 つのファイルの行をペアで連結して読みやすくなります。

paste user.txt contact.txt

これにより、2つのフィールドで構成されるタブで区切られたデータストリームが作成されます。

これは読みやすく簡単ですawk。たとえば、次のようになります。

awk -F '\t' '{ printf "user name is %s\nand his mobile number is %s\n\n", $1, $2 }'

これは出力文字列をprintf生成するために使用されます。awkの出力から読み取られた2つのフィールドはpaste自動的に読み取られ、$1出力$2文字列の表示された位置に挿入されます%s(引数として提供される次の文字列のプレースホルダprintf)。-F '\t'コマンドラインで、awkフィールド区切り記号をタブに設定します。

これら2つをまとめてテストしてみてください。

$ paste user.txt contact.txt | awk -F '\t' '{ printf "user name is %s\nand his mobile number is %s\n\n", $1, $2 }'
user name is apple
and his mobile number is 1234

user name is cat
and his mobile number is 3456

user name is tom
and his mobile number is 5678

>somenameコマンドの最後に使用してファイルにリダイレクトします。


もう1つのアプローチは、最初と2番目のフィールドの代わりに出力フィールドの区切り記号(OFS)と出力レコードの区切り文字()を変更することです(最後の末尾のために修正された行が出力されます)。ORSprintf1

paste user.txt contact.txt |
awk -F '\t' -v OFS='\n' -v ORS='\n\n' '{ $1 = "user name is " $1; $2 = "and his mobile number is " $2 }; 1'

答え3

bashmapfileファイルを1行に1つの要素として配列として読み取る組み込みコマンドがあります。-t末尾の改行を削除します。その後、配列を繰り返すことができます。

#!/bin/bash
mapfile -t user <user.txt
mapfile -t number <contact.txt
for (( i=0 ; i<${#user[@]} ; i++ )) ; do
  echo "user name is ${user[i]}"
  echo "and his mobile number is ${number[i]}"
  echo
done

答え4

そしてzsh

users=( ${(f)"$(<users.txt)"} )
numbers=( ${(f)"$(<numbers.txt)"} )
printf 'user name is %s\nand their mobile is %s\n\n' ${users:^numbers}

${A:^B}${A:^^B}2つの配列圧縮演算子です。 2つの配列の長さが異なる場合、2つの間の違いを見ることができます。A=(a b c) B=(1 2 3 4 5)この場合は、${A:^B}Yield a 1 b 2 c 3(一致から超過分を削除B)と${A:^^B}Yield a 1 b 2 c 3 a 4 b 5A超過分一致のためにメンバーを再利用)がありますB

関連情報