次の内容でテキストファイルを作成しようとしています。
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
)と出力レコードの区切り文字()を変更することです(最後の末尾のために修正された行が出力されます)。ORS
printf
1
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
bash
mapfile
ファイルを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
5
(A
超過分一致のためにメンバーを再利用)がありますB
。