テキストファイルから行を読み取り、各行の名前ごとにテキストファイルを作成する


21

次のようなテキストファイルがあるとします。

john
george
james
stewert

すべての名前を別々の行に入れます。

:私は次のように、このテキストファイルの行を読み、それぞれの名前のテキストファイルを作成したいjohn.txtgeorge.txtなど

Bashでこれを行うにはどうすればよいですか?


2
拡張機能が必要ですか?Linuxでテキストファイルにtxt拡張子が付いている理由はありません。
テルドン

回答:


18

#1 Bash +の使用touch

while read line; do touch "$line.txt"; done <in
  • while read line; [...]; done <in:これはreadreadそれ自体が戻るまで実行され1、ファイルの終わりに達したときに発生します。の入力readin<inリダイレクトのためにターミナルからではなく、現在の作業ディレクトリで指定されたファイルから読み取られます。
  • touch "$line.txt"この実験touchの拡大値で$line.txtの含有量で、line続い.txttouch存在しない場合はファイルを作成し、存在する場合はアクセス時間を更新します。

#2 xargs+ を使用するtouch

xargs -a in -I name touch name.txt
  • -a in:現在の作業ディレクトリにxargsあるファイルから入力を読み取りますin
  • -I namexargsすべての出現をname次のコマンドの現在の入力行に置き換えます。
  • touch nametouchの置き換えられた値で実行されnameます; 存在しない場合はファイルを作成し、存在する場合はアクセス時間を更新します。
% ls
in
% cat in
john
george
james
stewert
% while read line; do touch "$line.txt"; done <in
% ls
george.txt  in  james.txt  john.txt  stewert.txt
% rm *.txt
% xargs -a in -I name touch name.txt
% ls
george.txt  in  james.txt  john.txt  stewert.txt

read line実際に行をどのように読みますか?@kos
kashish

@kashish <inafter donereadwhileループ条件で各反復inでin から1行を読み取って保存しlineます。この方法でtouch "$line.txt"は、ループの内側が読み取り行に拡張さ.txtれ、最後になります。
コス

while read line; do touch "$line.txt"; done <in一人で仕事をしますか?ソースファイルはどこにありますか?
カシッシュ

@kashish確かに、これらは代替方法です。どちらか一方を使用することを意図しています。
コス

1
@kashishの仕組みreadです。をご覧くださいhelp read
テルドン

18

この特定のケースでは、1行につき1つの単語しかありませんが、次のこともできます。

xargs touch < file

ファイル名にスペースを含めることができる場合、これは破損することに注意してください。そのような場合、代わりにこれを使用してください:

xargs -I {} touch {} < file

ちょっとした楽しみのために、ここに他のいくつかのアプローチがあります(両方ともスペースを含む行を含む任意のファイル名を処理できます):

  • Perl

    perl -ne '`touch "$_"`' file
  • Awk

    awk '{printf "" > $0}' file 

Linuxおよび同様のシステムでは、大部分のファイルの拡張子はオプションです。.txtテキストファイルに拡張子を追加する理由はありません。あなたは自由にそうすることができますが、まったく違いはありません。したがって、とにかく拡張機能が必要な場合は、次のいずれかを使用します。

xargs -I {} touch {}.txt < file
perl -ne '`touch "$_.txt"`' file
awk '{printf "" > $0".txt"}' file 

7

AWKもこのタスクに適しています。

testerdir:$ awk '{system("touch "$0)}' filelist

testerdir:$ ls
filelist  george  james  john  stewert

testerdir:$ awk '{system("touch "$0".txt")}' filelist                          

testerdir:$ ls
filelist  george.txt  james.txt  john.txt  stewert.txt
george    james       john       stewert

別の方法、tee。ファイルリストに複数の文字列が含まれる行があると、このアプローチは失敗することに注意してください。

testerdir:$ echo "" | tee $(cat filelist)


testerdir:$ ls
filelist  george  james  john  stewert

また、</dev/null tee $(cat filelist)配管を避けたい場合は、同様に行うことができます

cp /dev/null アプローチ(これが示すように、これはスペースを含むファイル名で動作します):

testerdir:$ cat filelist | xargs -I {}  cp /dev/null  "{}"                     

testerdir:$ ls
filelist  FILE WITH SPACES  george  james  john  stewert

testerdir:$ ls FILE\ WITH\ SPACES                                              
FILE WITH SPACES

1
@kosファイルの各行に1行に1つの文字列が含まれている場合、1行に1つのファイルが作成されます。これは実質的にと同じecho "" | tee file1 file2 file2です。ただし、ファイル名にスペースが含まれている場合は破損します。
セルギーKolodyazhnyy

7

テキストファイルがあるとしましょう…

たとえば、答えがあります;)

awk '{system("touch \""$0".txt\"")}' file

また、スペースと接尾辞=)で防水

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.