อ่านบรรทัดจากไฟล์ข้อความและสร้างไฟล์ข้อความสำหรับแต่ละชื่อในแต่ละบรรทัด


21

สมมติว่าฉันมีไฟล์ข้อความเช่น:

john
george
james
stewert

ด้วยทุกชื่อในบรรทัดแยกต่างหาก

ฉันต้องการที่จะอ่านบรรทัดของไฟล์ข้อความนี้และสร้างแฟ้มข้อความสำหรับแต่ละชื่อที่ชอบ: john.txt, george.txtฯลฯ

ฉันจะทำสิ่งนี้ใน Bash ได้อย่างไร


2
คุณต้องการส่วนขยายหรือไม่? ไม่มีเหตุผลที่ไฟล์ข้อความจะมีส่วนขยาย txt ใน Linux
terdon

คำตอบ:


18

# 1 ใช้ Bash + touch:

while read line; do touch "$line.txt"; done <in
  • while read line; [...]; done <in: สิ่งนี้จะทำงานreadจนกว่าจะreadกลับมาเอง1ซึ่งจะเกิดขึ้นเมื่อเมื่อถึงจุดสิ้นสุดของไฟล์ อินพุตสำหรับreadถูกอ่านจากไฟล์ที่มีชื่อinในไดเร็กทอรีการทำงานปัจจุบันแทนจากเทอร์มินัลเนื่องจากการ<inเปลี่ยนทิศทาง
  • touch "$line.txt": สิ่งนี้จะทำงานtouchในมูลค่าที่ขยายตัวของ$line.txtซึ่งเป็นเนื้อหาของlineตามด้วย.txt; touchจะสร้างไฟล์หากไม่มีอยู่และอัปเดตเวลาในการเข้าถึงหากมีอยู่

# 2 ใช้xargs+ touch:

xargs -a in -I name touch name.txt
  • -a in: ทำให้xargsอ่านอินพุตจากไฟล์ที่มีชื่อinในไดเร็กทอรีการทำงานปัจจุบัน
  • -I name: ทำให้xargsแทนที่ทุกครั้งที่เกิดขึ้นnameด้วยบรรทัดปัจจุบันของอินพุตในคำสั่งดังต่อไปนี้
  • touch name: ทำงานtouchบนค่าแทนที่ของ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 <inหลังจากdoneทำreadในสภาพลูwhileปอ่านและเก็บหนึ่งบรรทัดจากinในlineที่ซ้ำแต่ละครั้ง; ด้วยวิธีนี้touch "$line.txt"ภายในลูปจะถูกขยายไปยังบรรทัดการอ่านด้วย.txtในตอนท้าย
kos

จะทำงานwhile read line; do touch "$line.txt"; done <inคนเดียวได้ไหม ไฟล์ต้นฉบับอยู่ที่ไหน
kashish

@kashish แน่นอนว่าพวกเขาเป็นวิธีการทางเลือก: คุณตั้งใจจะใช้อย่างใดอย่างหนึ่ง
kos

1
@kashish นั่นเป็นวิธีการreadทำงาน help readดู
terdon

18

ในกรณีนี้โดยเฉพาะที่คุณมีเพียงคำเดียวต่อบรรทัดคุณสามารถทำสิ่งต่อไปนี้

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 หากแต่ละบรรทัดในไฟล์มีหนึ่งสตริงต่อหนึ่งบรรทัดแน่นอนมันจะสร้างไฟล์ต่อบรรทัด มัน effectivelly echo "" | tee file1 file2 file2เดียวกับ แต่มันจะพังถ้าชื่อไฟล์มีช่องว่าง
Sergiy Kolodyazhnyy

7

สมมติว่าฉันมีไฟล์ข้อความ ...

สมมติว่าฉันมีคำตอบ;)

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

กันน้ำยังมีช่องว่างและมีคำต่อท้าย=)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.